bugfix> javascript > 投稿

私のコード:

$('#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 のリンクがあります 、クリックイベントコールバックをバインドしていることがわかります。

問題は: ユーザーが最初にリンクをクリックしたとき、コールバックは呼び出されません。コールバックは、ユーザーがもう一度クリックしたときにのみ呼び出されます。

なぜそれが起こったのか理解できませんか?誰も私を助けることができますか? どうもありがとう。

回答 3 件
  • 問題は、曲をクリックすると、テキストボックスへのフォーカスが同時に失われるために発生します。これにより、テキストボックスの「変更」イベントが発生し、曲リストがクリアされるため、クリックしたばかりの曲要素は存在しなくなり、「クリック」ハンドラーが実行される前に発生します。

    もちろん、曲は即座に同一に見えるものに置き換えられ、実際には単なる双子であるにもかかわらず、同じHTML要素を見ていると思わせるような錯覚を与えます。

    私の意見では、ここでの最良のオプションは、単に処理されたイベントのリストから「変更」イベントを削除することです。したがって、検索イベントハンドラは次のようになります。

    $('#search-form').on('keyup paste', function(event) {
    
    

    デモについては、http://jsfiddle.net/0j15ruz9/26/を参照してください。

  • 最初のハンドラーからkeyupイベントを削除するだけです。変更イベントは、必要なケースをカバーし、最初のクリックで正しく機能します。

    最初のクリックで、最初のイベントハンドラーが最初にトリガーされ、何かが台無しになります。

  • 私は何度か同じ問題に苦しんでいました、その理由はわかりません(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);
    ...
    
    

あなたの答え