2017-10-01 4 views
0

私はAJAXリクエストを起動し、<div> ($container)要素をHTMLで埋め込む入力フィールドを持っています。AJAXの成功関数のクリックハンドラがすべての要素にバインドされていないのはなぜですか?

JSONノードresponse.resultsHTML$containerに追加されるHTMLが含まれている、HTMLは次のようになります。

<div class="js_livesearch livesearch"> 
    <div class="js_livesearch_results livesearch_results"> 
    <div class="js_livesearch_result livesearch_result" data-id="3">item_1</div> 
    <div class="js_livesearch_result livesearch_result" data-id="2">item_2</div> 
    <div class="js_livesearch_result livesearch_result" data-id="1">item_3</div> 
    <div class="js_livesearch_result livesearch_result" data-id="4">item_4</div> 
    </div> 
</div> 

AJAX呼び出しを実行し、DOMのルックスにAJAXレスポンスのHTMLを追加するJavaScript/jQueryの次のように:今

$liveSearchTrigger.on('input', function() { 
     var search = this.value; 
     if (search) { 
      $.ajax({ 
       url: '/ajax/livesearch/' + $(this).data('identifier'), 
       type: 'POST', 
       dataType: 'JSON', 
       data: { 
        search: search 
       }, 
       success: function (response) { 
        if (response.success) { 
         if (response.resultsCount) { 
          $container.html(response.resultsHTML); 

          $container.find('.js_livesearch_result').each(function() { 
           var $result = $(this); 

           //this is being called correctly for EVERY SINGLE $result 
           alert("found: " + $result.text()); 

           //this is only sporadically bound to $result, not every single $result has the click handler - WHY? 
           $result.on('click', function() { 
            $liveSearchTrigger.val($result.text()); 
            alert('attempting to set ' + $result.text()); 
           }); 
          }); 

          reLayout(); 
          $container.slideDown(150); 
         } else { 
          $container.slideUp(150); 
         } 
        } 
       } 
      }); 
     } else { 
      $container.slideUp(150); 
     } 
    }); 

は、$container.html(response.resultsHTML);を使用してDOMに新しく生成されたHTMLを追加した後、私はすべての単一$('.js_livesearch_result')の要素にクリックイベントをバインドします。

$container.find('.js_livesearch_result').each(function() { ... });範囲では、アラートは「item_1」は、item_2' すべての.js_livesearch_result項目に呼ばれ、それがに警告している、[...]すべての要素のが、$result.on('click', function() { ... });は、それらのすべてにバインドされていません。場合によっては最初の2つだけ、時には3つはクリックイベントにバインドされています。

私が間違って何をやっているすべての単一.js_livesearch_result要素がバインドクリックハンドラを持っているように?、動的に生成.js_livesearch_result要素とどのように私は適切にイベントをバインドしないにクリックイベントをバインドしようとしていますか

編集:ここでは

は、それゆえ私はまだ$('.js_livesearch_result').on('click', function() {...});が正常に動作しない場合は、いくつかのより多くの(更新)コードです:

$liveSearchTrigger要素のHTML:

<input class="js_livesearch" type="text" name="key" value="" data-identifier="langkey" autocomplete="off" /> 

$containerに付加されるresponse.resultsHTML構造:

$(document).ready(function() { 
    $('.js_livesearch').liveSearch(); 
}); 

livesearch.js(プラグイン)::私はにに追加されているすべての.js_livesearch_resultの要素をクリックイベントをバインドするにはどうすればよい

(function ($, window) { 

    $.fn.liveSearch = function (options) { 

     var defaults = { 
      highlightCSS: { 
       'background-color': "lightgoldenrodyellow", 
      } 
     }; 

     var settings = $.extend({}, defaults, options); 



     var $liveSearchTrigger = $(this); 


     var searchUID = Math.floor(Math.random() * 26) + Date.now(); 
     var $container = $('.js_livesearch_uid' + searchUID); 

     if (!$container.length) { 
      var $elem = $('<div>').addClass('js_livesearch_uid' + searchUID).addClass('hidden'); 
      $('body').append($elem); 
      $container = $('.js_livesearch_uid' + searchUID); 
     } 

     $liveSearchTrigger.on('input', function() { 
      var search = this.value; 
      if (search) { 
       $.ajax({ 
        url: '/ajax/livesearch/' + $(this).data('identifier'), 
        type: 'POST', 
        dataType: 'JSON', 
        data: { 
         search: search 
        }, 
        success: function (response) { 
         if (response.success) { 
          if (response.resultsCount) { 
           $container.html(response.resultsHTML); 

           //this works fine if uncommented, every single 
           //element gets a highlight applied 
//        $container.find('.js_livesearch_result').each(function() { 
//         $(this).highlight(search, settings.highlightCSS); 
//        }); 

           //this does not work consistently, sometimes the first 3 (out of 4) 
           //items will bind the click handler sometimes only the first two 
           //elements will bind the click handler 
           $container.on('click', '.js_livesearch_result', function() { 
            console.log('Clicked: ' + $(this).text()); 
           }); 

           //another test which didn't work: 
//        $container.find('.js_livesearch_result').each(function() { 
//         $(this).unbind('click.resultItemClick').bind('click.resultItemClick', function() { 
//          console.log('Clicked: ' + $(this).text()); 
//         }); 
//        }); 

           reLayout(); 
           $container.slideDown(150); 
           $container.removeClass('hidden'); 
          } else { 
           $container.slideUp(150); 
           $container.addClass('hidden'); 
          } 
         } 
        } 
       }); 
      } else { 
       $container.slideUp(150); 
       $container.addClass('hidden'); 
      } 
     }); 

     $(window).resize(function() { 
      reLayout(); 
     }); 

     $liveSearchTrigger.on('focus', function() { 
      reLayout(); 
      $container.slideDown(150); 
      $container.removeClass('hidden'); 
     }); 

     $liveSearchTrigger.on('blur', function() { 
      $container.slideUp(150); 
      $container.addClass('hidden'); 
     }); 

     function reLayout() { 
      var position = $liveSearchTrigger.position(); 
      var layoutCSS = { 
       'position': 'absolute', 
       'z-index': '1000', 
       'top': (position.top + $liveSearchTrigger.outerHeight()) + 'px', 
       'left': position.left + 'px', 
       'width': $liveSearchTrigger.outerWidth() + 'px' 
      }; 
      $container.css(layoutCSS); 
     } 

     return this; 
    }; 

}(jQuery, window)); 

page.js

<div class="js_livesearch_results livesearch_results"> 
    <div class="js_livesearch_result livesearch_result" data-id="3">menu_code</div> 
    <div class="js_livesearch_result livesearch_result" data-id="2">menu_gallery</div> 
    <div class="js_livesearch_result livesearch_result" data-id="1">menu_home</div> 
    <div class="js_livesearch_result livesearch_result" data-id="4">menu_user</div> 
</div> 
は、プラグインを初期化しますAJAX経由のDOM?

+0

動的に追加されたDOM要素にイベントハンドラを追加する方法を尋ねていますか? –

+0

はい。私はAJAX経由でいくつかの '

item
'を追加しようとしており、これらの新たに追加された要素にクリックイベントをバインドしています。何らかの理由で、要素のすべて(必ずしもそうではない)がクリックハンドラを受け取るわけではなく、それらの束のためだけに(ランダムに)機能します。私はすでに、@ Rory McCrossanが提案したことを、何の不運もなく試しました。より多くのコードを投稿するつもりですが、最初はバインドが発生するAJAXの部分自体が間違いを犯していると思っていましたが、今は他のどこかで行方不明になっていると思います。 – phew

+1

イベントのバブリングまたは委任を検索します。 –

答えて

0

だから、問題は、1つの問題を修正することを取り除く、$liveSearchTrigger.on('blur', ...)でした!

関連する問題