私は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?
動的に追加されたDOM要素にイベントハンドラを追加する方法を尋ねていますか? –
はい。私はAJAX経由でいくつかの '
イベントのバブリングまたは委任を検索します。 –