1

私が取り組んでいるプロジェクトのために、次のコードを書きました。

var clicky_tracking = [
  ['related-searches', 'Related Searches'],
  ['related-stories', 'Related Stories'],
  ['more-videos', 'More Videos'],
  ['web-headlines', 'Publication']
];

for (var x = 0, length_x = clicky_tracking.length; x < length_x; x++) {
  links = document.getElementById(clicky_tracking[x][0])
                  .getElementsByTagName('a');
  for (var y = 0, length_y = links.length; y < length_y; y++) {
    links[y].onclick = (function(name, url) {
      return function() {
        clicky.log(url, name, 'outbound');
      };
    }(clicky_tracking[x][1], links[y].href));
  }
}

私がやろうとしていることは:

  • id2次元配列を定義します。各インスタンスには、属性値(「関連検索」など)と対応する説明(「関連検索」など)の2つの要素を含む内部配列が含まれます。
  • 内部配列ごとにdocument、対応する属性を持つ要素を見つけて、その中のすべての要素(ハイパーリンク)idのコレクションを収集します。<a>
  • onclickそのコレクションをループし、各ハイパーリンクにハンドラーをアタッチします。このハイパーリンクは、clicky.logに対応する説明id(たとえば、id「related-searches」の「Related Searches」)と要素のhref属性の値をパラメーターとして渡します。<a>それがクリックされました。

うまくいけば、それは完全に混乱していませんでした!コードはそれよりも自明かもしれません。

ここで実装したのはクロージャーだと思いますが、JSLintは次のように不平を言います。

http://img.skitch.com/20100526-k1trfr6tpj64iamm8r4jf5rbru.png

だから、私の質問は次のとおりです。

  • このコードをリファクタリングしてJSLintを快適にするにはどうすればよいですか?または、さらに良いことに、JSLintの考え方に関係なく、私が見逃しているこれを行うためのベストプラクティスの方法はありますか?
  • 代わりに、イベントの委任に依存する必要がありますか?つまり、配列内の属性を持つ要素にonclickイベントハンドラーをアタッチしてから、 ?私は以前にそれを行って理論を理解しましたが、詳細については非常に曖昧であり、これが実行可能なアプローチであると仮定して、それがどのように見えるかについてのガイダンスをいただければ幸いです。documentidevent.target

助けてくれてありがとう!

4

3 に答える 3

1

このコードはあまり保守できません!私はあなたの喉にjQueryを押し込むのは嫌いですが、これはあなたにとって非常に役立つ状況のように見えます。

$('a.trackable').click(function(e) {

  clicky.log(url, name, 'outbound');
};

各リンクにクラス「trackable」を追加することで追跡を有効にし、たとえば$(this).attr('rel')を使用してリンクをルックアップテーブルにマップできます。

それが理にかなっていることを願っています。

于 2010-05-26T05:55:49.530 に答える
1

イベントハンドラーを作成する関数を作成できます。例:

function createClickHandler(url, name) {
  return function () {
    clicky.log(url, name, 'outbound');
  };
}

for (var x = 0, length_x = clicky_tracking.length; x < length_x; x++) {
  links = document.getElementById(clicky_tracking[x][0]) // NOTE:links should be 
                  .getElementsByTagName('a');            // declared at the top
  for (var y = 0, length_y = links.length; y < length_y; y++) {
    links[y].onclick = createClickHandler(clicky_tracking[x][1], links[y].href);
  }
}

また、イベントの委任も非常に優れたオプションだと思います。非常に簡単に実装できます。

var clicky_tracking = [
  ['related-searches', 'Related Searches']
  //...
], elem;

function createClickHandler(name) { // capture only the 'name' variable
  return function (e) {
    e = e || window.event; // cross-browser way to get the event object
    var target = e.target || e.srcElement; // and the event target

    if (target.nodeName == "A") { // make sure that the target is an anchor
      clicky.log(target.href, name, 'outbound');
    }
  };
}

for (var x = 0, len = clicky_tracking.length; x < len; x++) {
  elem = document.getElementById(clicky_tracking[x][0]); // find parent element
  elem.onclick = createClickHandler(clicky_tracking[x][1]); // bind the event
}
​
于 2010-05-26T05:58:22.793 に答える
1

委任はより良いアプローチです。ループ内で毎回新しい関数を作成しているため、JSLintは文句を言います。ただし、すべてのクリックイベントをリッスンするようにドキュメントに単一のイベントを設定する代わりに、IDが割り当てられているすべての個々のルート要素にハンドラーを設定したいと思います。これらすべての要素に対して単一のハンドラーを再利用できます。

function logClick(event) {
    event = event || window.event;
    var link = event.target || event.srcElement;

    if(link.nodeName.toLowerCase() !== "a") {
        return;
    }

    var name = clicky_tracking[this.id];
    clicky.log(link.href, name, 'outbound');
}

上記のハンドラーを各ルート要素に登録します。

for(var id in clicky_tracking) {
    var root = document.getElementById(id);
    root.onclick = logClick;
}

また、配列を検索しないようにするためにclicky_tracking、キーアクセスを容易にするために配列からオブジェクトに変更しました。

var clicky_tracking = {
  'related-searches': 'Related Searches',
  'related-stories': 'Related Stories',
  'more-videos': 'More Videos',
  'web-headlines': 'Publication'
};
于 2010-05-26T06:06:10.760 に答える