【问题标题】:Jquery .click() function selector issueJquery .click() 函数选择器问题
【发布时间】:2017-08-16 01:11:03
【问题描述】:

我目前正在构建一个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; 隐藏文章,直到用户点击“查看更多”按钮。

我用下面的 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 选择器的情况下执行完全相同的代码时,它可以工作并且所有文章和按钮都会显示或隐藏。

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

【问题讨论】:

  • 您确定在悬停元素时添加了active 类吗?
  • @RoryMcCrossan .active 是某个地方的标记。而OP只需要使用thisclosest()
  • $('#search_container').on('click', '.active .more', function() {
  • @u_mulder 谢谢 - 我错过了hover 活动
  • 除此之外,$('#search_container .article') 将匹配 所有 &lt;tr class='article'&gt; 元素。你需要在你的桌子上使用ids 或使用$(this)parentclosest 的一些技巧。

标签: javascript php jquery html mysqli


【解决方案1】:

好问题。这与所使用的选择器的范围有关。在您的 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);

这个实现有几个缺点。每次您将鼠标悬停时,都会注册单击事件。每次您对其进行模糊处理时,都会取消设置单击绑定以防止随后的悬停双重绑定单击事件。由于您的所有目标类都包含在 .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 的范围内运行,从而允许一次注册它们。希望这会有所帮助。

【讨论】:

  • 这正是我想要的。并且解释得很好。非常感谢
【解决方案2】:

我认为原因是,当您创建事件侦听器时,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 匹配的元素。

【讨论】:

    【解决方案3】:

    问题是因为您正在动态添加/删除 .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);
    

    【讨论】:

    • 我不相信如果你点击两次.more 它会再次隐藏元素
    • 好的,错过了。
    • 这仍然不起作用:s 知道为什么它不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 2011-10-31
    • 2010-12-01
    • 2010-11-25
    相关资源
    最近更新 更多