我的代码:
$('#search-form').on('keyup change paste', function(event) {
$('#songs').empty();
$('#aplayer').css('display', 'none');
var keyword = $('#keyword').val();
if (keyword.trim() === '') {
return;
}
const relatedSongs = songs.filter(function(song) {
return song.name.includes(keyword);
});
$('#songs').append(relatedSongs.map(function(song) {
return '<li class="list-group-item" data-index="' + song.index + '"><a href="#" class="song-name">name:' + song.name + '</a></li>';
}));
});
$('#songs').on('click', '.song-name', function() {
const index = $(this).parent().data('index');
const song = songs[index];
ap.list.clear();
ap.list.add(song);
$('#aplayer').css('display', 'block');
});
关键是$('#songs').append
,我动态创建元素并将它们附加到#songs元素中。
所有动态创建的元素都有一个类song-name
的链接,您会注意到我在它们上绑定了一个click事件回调。
问题是: 当用户第一次单击链接时,不会调用回调。仅当用户再次单击该回调时,该回调才会被调用。
我不明白为什么会这样?谁能帮我? 非常感谢。
答案 0 :(得分:1)
发生此问题的原因是,当您单击一首歌曲时,您同时失去了对文本框的关注。这将触发文本框的“ change”事件,然后清除歌曲列表,因此您刚刚单击的歌曲元素不再存在,并且在其“ click”处理程序有机会执行之前发生。
当然,这首歌会立即被看起来相同的那首歌取代,给您一种视觉上的错觉,使您相信您仍然在看相同的HTML元素,而实际上它只是一对孪生。
我认为最好的选择只是从已处理事件的列表中删除“更改”事件-这是多余的,因为只要输入任何文本,键控和/或粘贴操作便会在其之前触发。因此,您的搜索事件处理程序将变为:
$('#search-form').on('keyup paste', function(event) {
请参见http://jsfiddle.net/0j15ruz9/26/进行演示。
答案 1 :(得分:0)
只需从您的初始处理程序中删除keyup事件。更改事件将涵盖您需要的情况,并且在第一次单击时将正常运行。
第一次单击时,首先触发第一个事件处理程序,结果有些混乱。
答案 2 :(得分:-1)
我几次遇到相同的问题,我不知道是什么原因(我想这是与DOM实现有关的事情发生的原因),但是我以这种方式解决了
function song_name_click(e){
const index = $(this).parent().data('index');
const song = songs[index];
ap.list.clear();
ap.list.add(song);
$('#aplayer').css('display', 'block');
}
...
$('#songs').append(relatedSongs.map(function(song) {
return '<li class="list-group-item" data-index="' + song.index + '"><a href="#" class="song-name">name:' + song.name + '</a></li>';
}));
$(".song-name").off('click');
$(".song-name").on('click', song_name_click);
...