1

ここにツールチップを作成する関数があります。これらのツールチップは無限スクロールのページに作成されます (たとえば、ページの一番下に到達するとすぐに、関数が再度呼び出されます)。私のツールチップ機能と同時に再初期化されるカスタムスクロール。

問題は、関数が再初期化されるたびに、ツールチップが一度に複数の画像でいっぱいになり、無限スクロール コールバックの再初期化ごとに重複することです。

これは機能です:

function tooltipsInit() {

      //Setting the targeted elements variable
      var appliesTo = '.products .products-grid li .product-image-visible a, .featured .products-grid li .product-image-visible a, .new .products-grid li .product-image-visible a, .popular .products-grid li .product-image-visible a';
      jQuery(appliesTo).mouseenter(function() {
        jQuery(this).children('p').addClass('active');
        if((navigator.platform.indexOf("iPad") != -1) || (navigator.platform.indexOf("iPhone") != -1)) {
          //disabling the tooltips on iPad/iPhone
        } else {
          jQuery('body .wrapper').append('<div class="hcontainer"><div class="image"></div><div class="title"></div></div>');
          jQuery(this).children('img').clone().appendTo('.hcontainer .image');
          title = jQuery(this).children('img').attr('alt');
          jQuery('.hcontainer .title').append(title);
          jQuery('.hcontainer').fadeIn(200);

          function removeDuplicates() {
            //THIS IS MY QUESTION RELATED TO
            jQuery.removeData();
          }
          removeDuplicates();
        }
      });
      jQuery(appliesTo).mousemove(function(e) {

        offsetX = 235;
        offsetY = 175;

        windowHeight = jQuery(window).height();
        windowWidth = jQuery(window).width();
        ypos = 0;
        xpos = 0;

        if((e.pageY + 355) < windowHeight) {
          ypos = e.pageY + offsetY;
        } else {
          ypos = e.pageY - (offsetY + 30);
        }

        if((e.pageX + 455) < windowWidth) {
          xpos = e.pageX + offsetX;
        } else {
          xpos = e.pageX - (offsetX + 30);
        }

        jQuery(".hcontainer").css("top", (ypos) + "px").css("left", (xpos) + "px");
      });

      jQuery(appliesTo).mouseleave(function() {
        jQuery(this).children('p').removeClass('active');
        jQuery('.hcontainer').fadeOut(100).remove();

      });


    };

このように、DOM データ全体をクリアしています (そうですか?)。Chrome 開発ツールでいくつかのエラーが発生します。

Uncaught TypeError: Cannot read property 'nodeName' of undefined jquery-1.8.3.min.js:1719
jQuery.extend.acceptData jquery-1.8.3.min.js:1719
jQuery.extend.removeData jquery-1.8.3.min.js:1633
removeDuplicates custom-scripts.js:160
(anonymous function) custom-scripts.js:162
jQuery.event.special.(anonymous function).handle jquery-1.8.3.min.js:3344
jQuery.event.dispatch jquery-1.8.3.min.js:3058
elemData.handle.eventHandle

DOM に追加されるデータを正確に選択し、それのみを削除するにはどうすればよいですか?

お気に入り:removeData(mytooltipfunctionsData)

また、同じトピックについて、私はJavascript/jQueryにかなり慣れていませんが、どのように機能を改善しますか?


編集

私はばかです...私はあなたがそこに書いたものを詳しく見て、呼び出される関数内でまだ実行していました...そして、あなたがそこに作ったものは関数を必要としないことに気付きました.あなたが言った、それはイベント委任です:)。

ありがとう、うまくいきました!無限スクロールでの重複やエラーはありません。

4

1 に答える 1

0

jQueryremoveDataオブジェクトではなく、DOM ノードを jQuery に渡す必要があります。jQuery.removeData($(this));たとえば、行う代わりに、行う必要がjQuery.removeData(this)あるか、セレクターを使用している場合は、jQuery.removeData($('.selector')[0])

重複については、現在のdomがすでに初期化されている場合、次のように関数に通知する場合があります

jQuery(appliesTo).each(function(){
   var $this = $(this);

   if (!$this.data('initialized')){ // skip in case it's been already initialized
     $this.data('initialized', true);

     $this.on({
       'mouseenter': function(){...},
       'mousemove': function(){...},
       'mouseleave': function(){...}
     });
   }

});

の代わりにremoveData、IMO を使用する必要があります。likeoff()$this.off()、一致した要素内のすべてのバインドされたイベントを削除します。もう 1 つの方法は、イベント委任を使用することです。そのため、再初期化は必要ありません。次のように、新しい要素と古い要素に対してのみ機能します。

var appliesTo = '.products .products-grid li .product-image-visible a, .featured .products-grid li .product-image-visible a, .new .products-grid li .product-image-visible a, .popular .products-grid li .product-image-visible a';

jQuery(document)
.on('mouseenter', appliesTo, function(){...})  
.on('mouseleave', appliesTo, function(){...})  
.on('mousemove', appliesTo, function(){...});  

jQuery.onイベントまたはイベント委譲をバインドする現在推奨される方法です。デリゲートの 2 番目の方法jQuery(document)は、 の要素に関係なく常に存在するappliesToため、ページに追加された要素には、毎回手動で開始するのではなく、既に要素がバインドされています (ページの読み込み、ajax イベントなど)。

于 2012-12-06T16:16:12.353 に答える