【问题标题】:Rationale behind $(this) in jQueryjQuery 中 $(this) 背后的基本原理
【发布时间】:2014-12-19 14:39:06
【问题描述】:

我正在尝试使用 jQuery 生成一个小脚本,但遇到了障碍。我的脚本是关于使用 trHighlight 类将每个单击的表格的 <tr> 对象转换为特定样式:

$(document).ready(function() {          
    $('tr').bind('click', function() {
    $(this).addClass('trHighlight');
    });
});

当再次单击表格的每一行(每个<tr> 对象)时,我现在正尝试返回正常 样式。我尝试了以下脚本:

$(document).ready(function() {          
    $('tr').bind('click', function() {
       $(this).addClass('trHighlight');
    });
    $('tr .trHighlight').bind('click', function() {
       $(this).removeClass('trHighlight');
    });
});

特定的if-结构也没有太大帮助。你有什么想法吗?

另一个问题:您是否有可以通过this.x 寻址的所有属性的描述,例如this.id - 也许我可以尝试使用“this”的类属性找到一种方法?

【问题讨论】:

  • 更改元素的类不会更改绑定到它的事件处理程序。
  • 您的第二个点击处理程序不起作用的原因是因为 1)选择器中有一个空格(如下面的 Bram 解释)和 2)您在点击处理程序之后添加了 .trHighlightclass已绑定。使用 on 可以完成这项工作,尽管 matthias_h 的解决方案是可行的方法。 $('table').on('click', 'tr.trHighlight', function() { $(this).removeClass('trHighlight'); });

标签: javascript jquery


【解决方案1】:

你可以只使用 toggleClass():

$(document).ready(function () {
  $('tr').bind('click', function () {
    $(this).toggleClass('trHighlight');
  });
});

并可能考虑将bind() 更改为on()。两者都可以工作,两者的优缺点都可以作为参考:jquery .bind() vs. .on()
您应该使用.on(),因为.bind() 已被弃用。但作为旁注 - bind()on() - http://james.padolsey.com/jquery/#v=2.0.3&fn=$.fn.bind 的重写函数(从这个答案中检索到的实际信息:jquery .bind() vs. .on()

【讨论】:

  • 终于成功了!非常感谢您,您可以理解我是 jQuery 的绝对初学者!
  • 记住.on()应该被使用而不是.bind()
  • 无论是这个,或者如果你真的想使用单独的点击处理程序,使用默认类:$('tr.default').click(function(){$(this).removeClass("default").addClass('trHighlight');});。 (反之亦然恢复正常)
  • @DarkAjax 感谢您的提及,我承认我没有处理 bind(),因为我只是想到了 toggleClass() 的使用。更新了答案。
【解决方案2】:

@matthias_h 他的答案是要走的路。但是,为了完整起见,我只想通知您,您有一个浮动空间,这是问题所在:$('tr .trHighlight') 选择一个元素(无论哪个),其类 trHighlight 是表行的后代。但是,您想要的是 具有 类本身而不是其后代之一的表行。可以通过连接类和元素来选择具有类的特定语义元素,如下所示:$('tr.trHighlight')。您的最终脚本将如下所示,但是 - 如前所述 - 在这种情况下您应该使用 matthias_h 的答案。

$(document).ready(function () {
    $('tr').bind('click', function () {
        $(this).addClass('trHighlight');
    });
    $('tr.trHighlight').bind('click', function () {
        $(this).removeClass('trHighlight');
    });
});

【讨论】:

    【解决方案3】:

    您对 JavaScript 的工作原理有些不理解。重要的是要知道 JavaScript 运行一次。运行后,它只监听(并在被要求时运行函数)。

    所以你当前在$('tr')$('tr . trHighlight') 上绑定事件(顺便说一下,标签和类名之间不应该有空格),但是只有当你点击类trHighlight 时才会添加tr。 JavaScript 运行时它不存在,因此没有将事件侦听器附加到将删除该类的元素。

    这就是为什么有一个事件委托系统。基本上,您在父静态元素上附加一个事件,它将向它学习并将事件目标与其祖先进行比较。如果比较匹配选择器,则事件将成功运行代码。

    我在这里谈论的是带有选择器作为参数的.on 方法。这段代码可以工作:

    $(document).ready(function() {          
        $('table').on('click', 'tr:not(.trHighlight)', function() {
            $(this).addClass('trHighlight');
        });
        $('table').on('click', 'tr.trHighlight', function() {
            $(this).removeClass('trHighlight');
        });
    });
    

    但在您的情况下不建议这样做。您只是在更改一个类,而 jQuery 有一个功能:.toggleClass

    这意味着您可以在tr 上绑定单个事件,无论他是否有课程。 .toggleClass 如果需要删除或添加类,将为您评估。这很简单:

    $(document).ready(function() {          
        $('tr').on('click', function() {
            $(this).toggleClass('trHighlight');
        });
    });
    

    【讨论】:

    • @AtoM_84 不过那会比我更难...这个概念不是那么简单,而且我也不是以英语为母语的人!
    • 好吧,让我重新表述一下你的一些陈述,以确保我理解正确(对不起,我不是以英语为母语的人):1)你的意思是 JS 只能基于在加载文档后在 DOM 中的现有对象(及其相关属性)上,因为这是实际执行的时间?我对吗? 2)这就是我的脚本无法成功运行的原因:调用方法 removeClass 的函数基于一个选择器,导航器(或任何东西)在执行脚本时没有找到任何相关对象(假设代码是正确的写...)
    • 3) 最后你告诉我,我最好为我的脚本引用静态对象(这样脚本会被解释并且不会因为使用不适当的选择器而被认为没有用),并使用后代jQuery 的“效果”成功地执行了它们的操作。是真的吗?
    • @AtoM_84 你在第二点上是对的。它不起作用,因为选择器没有找到任何东西。不过,在您的第二点上,对象属性(或属性)是永久性的。一旦你改变它,它就会到处改变。关于第三点,我建议您使用静态事件。该事件直接绑定到元素而不是其父元素。这意味着无论您如何更改元素,事件将始终绑定到它并执行您告诉他执行的操作(功能)。在这种情况下,切换类。
    • 太好了,我现在对其他暂定脚本可能遇到的其他问题有了更好的理解。非常感谢,我把这个帖子作为一个最喜欢的网页来记住所有这些事情。
    猜你喜欢
    • 2011-03-11
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    相关资源
    最近更新 更多