0

ループ内の各リンク オブジェクトにonclickを付けるのに問題があります。リンクをクリックすると、クリックされたものに関係なく、ループ内の最初の項目に関連するデータが常に返されるようです。そのリンクに関連するhrefを取得するには、各リンクをクリックする必要がある場合

以下の例では、クリックされたリンクに関係なく、console.log には常に「http://example.com/link1/」と表示されます。

HTML の例

  <li>
    <h2><a class="t" href="http://example.com/link1/"><i>Link 1 text</i></a></h2>
    <div class="panel" >Content</div>
  </li>

  <li>
    <h2><a class="t" href="http://example.com/link2/"><i>Link 2 text</i></a></h2>
    <div class="panel" >Content</div>
  </li>

  <li>
    <h2><a class="t" href="http://example.com/link3/"><i>Link 3 text</i></a></h2>
    <div class="panel" >Content</div>
  </li>

</ul>

JavaScript:

(function(){
  var theh2s = document.getElementById("panelList").getElementsByTagName("h2"), 
  i = theh2s.length;

  while (i--) {

      var getTheLinks = theh2s[i].getElementsByTagName("a");

      if (getTheLinks){
        if (getTheLinks[0].href){

          console.log(getTheLinks[0].href);

          getTheLinks[0].onclick = function() {
            console.log(getTheLinks[0].href);
            _gaq.push(['_trackEvent', 'Homepage', 'AB Click - Test B', getTheLinks[0].href]);
          };


        }
      }

  }
})();
4

2 に答える 2

1

先に進み、この問題に対する私の推奨する解決策を示します

(function(){
  function processLinkClick(e) {
    var link = e.currentTarget;
    console.log(link.href);
    _gaq.push(['_trackEvent', 'Homepage', 'AB Click - Test B', link.href]);
  }

  var theh2s = document.getElementById("panelList").getElementsByTagName("h2"), 
  i = theh2s.length;

  while (i--) {

      var getTheLinks = theh2s[i].getElementsByTagName("a");

      if (getTheLinks){
          if (getTheLinks[0].href){

              console.log(getTheLinks[0].href);

              getTheLinks[0].onclick = processLinkClick;


          }
      }

   }
})();

...そして、はい、その関数はインライン化できます。より明確にするために、それを分割しました。

イベント関数はイベント オブジェクトを受け取ることを忘れないでください。イベントを処理するためのコンテキストを確立するために使用するのは、(可能であれば) それだけです。この場合、コンテキストは「クリックされたリンク」であり、イベントは囲んでいるコンテキストではなく、その質問に答えます。ソフトウェア設計の観点から、イベントを使用することはよりクリーンなソリューションになり、長期的には保守が容易になると私は主張します。

于 2013-11-14T16:21:57.807 に答える
1

問題は、クリックが発生したときに、getTheLinksすでにh2リストの最後に設定されていることです。各ループが前のループを上書きしないようにするには、クロージャを使用して、このパターンを使用して新しいコンテキストを作成する必要があります: (function(i){...})(i).

Felix Kling が言及したように、閉鎖は実際には問題の原因です。次の記事では、この概念について説明します。あなたが遭遇したこの一般的な落とし穴に関する段落があります: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures .

(function () {
    var theh2s = document.getElementById("panelList").getElementsByTagName("h2"),
        i = theh2s.length;
    while (i--) {
        (function (i) {
            var getTheLinks = theh2s[i].getElementsByTagName("a");
            if (getTheLinks) {
                if (getTheLinks[0].href) {
                    console.log(getTheLinks[0].href);
                    getTheLinks[0].onclick = function () {
                        console.log(getTheLinks[0].href);
                        _gaq.push(['_trackEvent', 'Homepage', 'AB Click - Test B', getTheLinks[0].href]);
                    };
                }
            }
        })(i);
    }
})();

私はJSLintに慣れていません。JSLintを有効にする必要がある場合は、次のように関数定義をループの外に移動する必要があると思います:

while (i--) {
    f(i)
}
function f(i) {
    // same as above
}
于 2013-11-14T15:37:04.953 に答える