Jquery .click()函数选择器问题

时间:2017-03-23 12:58:15

标签: javascript php jquery html mysqli

我目前正在构建一个PHP网页,该网页从SQL服务器检索数据,并将检索到的数据作为表格输出。每个<tr>都有自己的类,如下所示:

"<table class='preview'>
      <tr class='title'>
          <th>$pages->title</th>
      </tr>
      <tr class='info'>
          <td class='type static'>Type: </td>
          <td class='type dynamic'>$pages->type</td>
          <td class='auteur static'>Written by: </td>
          <td class='auteur dynamic'>$pages->author</td>
      </tr>
      <tr class='article'>
          <td colspan='4'>$pages->article</td>
      </tr>
      <tr class='btns'>
          <td colspan='4'>
             <button type='button' class='more'>
                  See more
             </button>
             <button type='button' class='less'>
                  See less
             </button>
          </td>
      </tr>
</table>"

由于篇幅较多且篇幅较长,我希望使用display: none;隐藏文章,直到用户点击&#34;更多&#34;按钮。

我使用以下jQuery代码执行此操作:

var main = function() {
$('#search_container .preview').hover(function(){
    $(this).toggleClass('active');
});

$('#search_container .active .more').click(function(){
    console.log('click');
    $('#search_container .active .less').show();
    $('#search_container .active .article').show();
    $('#search_container .active .more').hide();
    $('#search_container .active .info').hide();
});

$("#search_container .active .less").click(function(){
    $('#search_container .active .less').hide();
    $('#search_container .active .article').hide();
    $('#search_container .active .more').show();
    $('#search_container .active .info').show();
});
};
$(document).ready(main);

由于只需要显示所选文章,我决定添加第一个功能。但是.active .more.active .less的选择器似乎不起作用,因为当我执行完全相同的代码而没有.active选择器时,它可以工作,所有文章和按钮都显示或隐藏。

知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

好问题。这与所使用的选择器的范围有关。在您的javascript中,您提供了一种切换类的机制,但是当您更改类时,必须重新运行jQuery选择器以查找新添加的活动类。对您的JavaScript代码进行一些小的更改可以让您朝着正确的方向前进:

var main = function() {
    $('#search_container .preview').hover(
        function(){
            // Keeping this for your targeting
            $(this).addClass('active');
            $(this).find('.more').click(
                function(){
                    $('#search_container .active .less').show();
                    $('#search_container .active .article').show();
                    $('#search_container .active .more').hide();
                    $('#search_container .active .info').hide();
                }
            );
            $(this).find('.less').click(
                function(){
                    $('#search_container .active .less').hide();
                    $('#search_container .active .article').hide();
                    $('#search_container .active .more').show();
                    $('#search_container .active .info').show();
                }
            );
        },
        // When exiting hover, unbind the click bindings
        function(){
            // Keeping this for your targeting
            $(this).removeClass('active');
            // These keep only one .preview container bound to the commands
            // at a given moment
            $(this).find('.more').unbind('click');
            $(this).find('.less').unbind('click');
        }
    );
};

$(document).ready(main);

这种实现有几个缺点。每次悬停时,都会注册click事件。每次模糊它时,都会取消设置单击绑定,以防止后续悬停双重绑定click事件。由于您的所有目标类都包含在.preview中,我会尽力做到这样:

var main = function() {
    var previews = $('#search_container .preview');

    $.each(
        previews,
        function(){

            // Reference stored for the .preview container
            var ref = $(this);

            ref.find('.more').click(
                function(){
                    ref.find('.less').show();
                    ref.find('.article').show();
                    ref.find('.more').hide();
                    ref.find('.info').hide();
                }
            );

            ref.find('.less').click(
                function(){
                    ref.find('.less').hide();
                    ref.find('.article').hide();
                    ref.find('.more').show();
                    ref.find('.info').show();
                }
            );
        }
    );
};

$(document).ready(main);

现在,所有预览都会将.more.less项绑定到点击事件,并且点击事件在.preview的范围内运行,允许所有项目都在一旦。希望这会有所帮助。

答案 1 :(得分:0)

我认为原因是,当您创建事件侦听器时,DOM节点还没有准备好。因为没有元素有活跃类。而是尝试下面的脚本

var main = function() {
$('#search_container .preview').hover(function(){
    $(this).toggleClass('active');
});

$('#search_container').on('click', '.active .more', function(){
    console.log('click');
    $('#search_container .active .less').show();
    $('#search_container .active .article').show();
    $('#search_container .active .more').hide();
    $('#search_container .active .info').hide();
});

$('#search_container').on('click', '.active .less', function(){
    $('#search_container .active .less').hide();
    $('#search_container .active .article').hide();
    $('#search_container .active .more').show();
    $('#search_container .active .info').show();
});
};
$(document).ready(main);

这将在主容器上添加live事件侦听器,并等待任何匹配.active .more的元素。

答案 2 :(得分:0)

问题是因为您正在动态添加/删除.active类。在加载页面时,它不存在于任何元素上,因此不会绑定任何事件处理程序。

要解决此问题,请使用委派的事件处理程序:

var main = function() {
  $('#search_container .preview').hover(function() {
    $(this).toggleClass('active');
  });

  $('#search_container').on('click', '.active .more', function() {
    $(this).find('.active .less, .active .article').show();
    $(this).find('.active .more, .active .info').hide();
  }).on('click', '.active .less', function() {
    $(this).find('.active .less, .active .article').hide();
    $(this).find('.active .more, .active .info').show();
  });
};
$(document).ready(main);