21

JavaScriptアプリケーションで頭を悩ませる問題に遭遇しました。

このような要素を書くと:

<li onClick="alert(this.tagName)"></li>

「LI」を取得します。

しかし、私がこれを行う場合:

<li onClick="foo()"></li>

「foo()」は次のとおりです。

function foo(){ alert(this.tagName); }

「未定義」になります。

付属機能に関して「これ」がどのように機能するのか、私は離れています。しかし、「これ」は要素を取得しておらず、明らかにデフォルトで「ウィンドウ」になっているため、私は困惑しています。なぜこれが起こっているのか理解できません。

誰か説明がありますか?

4

5 に答える 5

29

これは、JavaScript関数呼び出しでこれへの参照を渡していないためです。JavaScript関数のこれは、 onClickの例と同じオブジェクトを参照していません。代わりにこれを試してください:

 <li onClick="foo(this)"></li>

 function foo(item){ alert(item.tagName); }
于 2012-09-18T22:47:42.063 に答える
4

インラインリスナーの場合:

> <li onClick="alert(this.tagName)"></li>

onclick属性値は効果的に関数にラップされ、これに設定された要素で呼び出されます。

function anon() {
  /* attribute value */
}

anon.call(element);

関数を本体に配置すると、基本的に次のようになります。

function anon() {
  foo();
}

ここでは、thiswithinanonが要素になりますが、fooを設定せずに呼び出されるためthis、未定義になります。非厳密モードでthisは、デフォルトでグローバルオブジェクト(windowブラウザ内)になります。厳密モードでは、this内部fooは未定義になります。

1つの解決策は、要素参照を関数に渡すことです。

<li onclick="foo(this)" ... >

次に、関数で:

function foo(callingElement) {
  ...
}

あるいは:

<li onclick="foo.call(this)" ... >

function foo() {
  var callingElement = this;
}
于 2012-09-18T22:53:28.357 に答える
2

他の回答ですでに述べたように、の値は、thisそれを含む関数がどのように呼び出されるかによって異なります。しかし、あなたの例はイベントハンドラーに関するものなので、cjc343がコメントで言ったことを強調したいと思います。

インラインイベントハンドラーを削除すると、より賢明な場合があります。

実際、これは非常に簡単です。このHTMLを検討する:

<ul id="list">
    <li id="item1">item 1</li>
    <li id="item2">item 2</li>
    <li id="item3">item 3</li>
</ul>

次のJavaScriptは、インラインハンドラーの削除と委任の使用の両方を考慮します。

var list = document.getElementById('list');
list.addEventListener('click', function(evt){
    console.log("this is the element the event is bound to: " + this.id);
    console.log("the event target is the clicked element: " + evt.target.id);
});

http://jsfiddle.net/J3Gje/

これは、IE9を含むW3Cイベントモデルに準拠するすべてのブラウザーで機能します。古いIEの場合は、attachEventの代わりにを使用addEventListenerし、イベント名の前に。を付ける必要があり"on"ます。詳細はこちら

于 2012-09-18T23:17:59.140 に答える
0

これをパラメータとして渡す必要がない別のオプションは、callまたはapplyを使用することです。これは、関数内でこれの値を設定するための組み込みメカニズムです。指摘しておきますが、イベントハンドラーをHTMLに直接追加するのは少し時代遅れです。イベント委任用のJSフレームワーク(jQueryPrototypeDojoYUIなど)を確認することをお勧めします。

フィドル: http: //jsfiddle.net/bboone/Q2CkV/2/

HTML

<div onClick='alert(this.tagName);'>test</div>
<div onClick='foo.call(this);'>test2</div>​

JS

function foo(){ alert(this.tagName); }
于 2012-09-18T22:56:07.623 に答える
-1

JavaScriptを初めて使用する場合は、thisornewキーワードを使用しないでください。間違ってしまうか、コードが不必要に非効率的で複雑になるためです。ただし、達成しようとしていることは次のとおりです。

<li onclick="foo(this)">some text</li>

その例では、そのリストアイテムのクリックイベントがfooという名前の関数を起動します。thisキーワードは変数として渡されます。キーワードはthis、問題の関数を呼び出したエンティティを参照するだけであり、そのエンティティが見つからない場合windowは、ブラウザのオブジェクトを参照します。この場合、関数を呼び出したエンティティはDOMのリストアイテムノードです。

thisこの種の混乱を避けるために、キーワードは絶対に使用しないことをお勧めします。

編集:また、これは標準ではないため、tagNameプロパティを使用しないでください。代わりに、nodeNameプロパティを使用してください。

于 2012-09-18T22:50:44.893 に答える