是否无法为 $(document) 上的 jqueryui/jqm 小部件事件设置 on() 侦听器?

Posted

技术标签:

【中文标题】是否无法为 $(document) 上的 jqueryui/jqm 小部件事件设置 on() 侦听器?【英文标题】:Is it not possible to set an on() listener for a jqueryui/jqm widget event on $(document)? 【发布时间】:2013-10-27 11:00:17 【问题描述】:

我正在尝试在$(document) 上设置一个全局事件绑定器,它植根于我的所有核心应用程序功能。

我正在使用一些 jQueryUI 小部件(来自 jQuery Mobile),并希望我也可以在我的全局处理程序中包含小部件事件。

所以我正在尝试这样做:

 $(document).on("click change filterablebeforefilter", ".action_elements", function (e) 
   // foo
 );

但是,这不起作用。我可以在我的小部件input 事件上设置单击和更改侦听器,但不能像这样设置filterablebeforefilter。至少我不能让它工作。

JQM demos 仅指定直接绑定:

 $( ".selector" ).on( "filterablebeforefilter", function( e, data ) 
  // foo
 );

问题: 但我想知道是否没有办法将事件附加到document

谢谢!

【问题讨论】:

你总是会提出棘手的问题;) 我想我也有一个答案......我认为 jQueryUI 小部件事件与“浏览器事件”不同,因此它们保持在其“领域”内并且不会在任何地方传播或冒泡,所以在文档上设置一个监听器是行不通的。还是需要确定 很好的问题,你的解释听起来很合理。您应该为此添加一个答案,这样它就不会仍然显示为未回答。此外,如果您确实想将侦听器挂在那么高的级别(这不仅仅是一个简单的示例),您可能应该更好地指定过滤元素 - 只需像 '.action_elements' 这样的单个类就可以给出性能不佳取决于您的文档结构 - 最好也指定元素类型,例如“div.action_elements”。 @John-NotANumber - 我最终选择了$(document).on("click change keyup input", ".action", function (e) ... 它很高而且相当“通用”,但它是我在我的应用程序中设置的唯一绑定(用于链接、输入和选择) .尚未测试这是否比单个绑定更高效,但它确实更容易维护:-) 【参考方案1】:

$(document) 上的自定义事件处理程序确实有效:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>OnEventHandler</title>
    <script src="Scripts/jquery-2.1.0.min.js"></script>
    <script language="javascript" type="text/javascript">
        $(document).ready(function () 
            $(document).on('click filterEvent', '.action_element', function () 
                alert('You Clicked Me!');
            );
            $('#OrderFilter').change(function () 
                $('#CustomerFilter').trigger('filterEvent');
            );
            $('#CustomerFilter').on('filterEvent', function () 
                alert('CustomerFilter filterEvent');
            );
        );
    </script>
</head>
<body>
    <p>Some text.</p>
    <p class="action_element">Click me!</p>
    <select id="OrderFilter">
        <option>By Order Id</option>
        <option>By Order Total</option>
    </select>
    <p id="CustomerFilter" class="action_element">Just some Text...</p>
</body>
</html>

您可以使用 $(document).on('event', 'selector') 为自定义事件委托处理程序。

编辑

因此,这排除了自定义事件传播到文档级别并由那里的委托事件处理程序处理的任何可疑事件。

查看JQM filter 和您的问题,您是否在问:如果他们单击输入框或输入框发生变化,或者小部件在开始对某些数据应用过滤之前就在,然后执行 function() ...?

如果意图是覆盖过滤过程以获取一些要过滤的数据,则在过滤完成之前,如文档所述;首先来自数据库(想到谷歌搜索......)它适用于手头的小部件是否有意义?如果您的应用程序中有多个小部件,您是否希望所有小部件都具有相同的数据数据库调用(例如同一页面上的 4 个谷歌搜索输入框?)

每个小部件的 beforefilter 事件必须是唯一的(想想 3 个文本框,一个用于 google,一个用于 yahoo,一个用于 bing)是有意义的。如果是这样,他们是如何做到这一点的,我还不知道(但我会尝试,因为我有兴趣知道......)

此外,在过滤器启动之前有 250 毫秒的延迟,因此它会等待查看用户是否已完成输入...随着更改事件也被委托,处理程序将为它执行,并完成或在触发 beforefilter 事件的 250 毫秒后完成的路上......所以处理程序被执行两次?不管有没有,有意义吗?

我猜,他们有它,所以每个小部件只能有一个 beforefilter 事件处理程序,按照上面解释的设计。另请注意,在文档示例中,它们使用 .on() 的直接绑定表示法(未指定选择器)。一切都指向一个元素的绑定,而不是委托。

【讨论】:

$(document).on(...)将事件处理程序附加到document$().delegate 只是 $().on 的别名,其参数已重新排序。 "越接近 '.action_elements' 的处理程序,越少遍历 DOM jQuery 必须做的事情,这意味着更少的处理和更好的性能。" - 这也不是真的。在 any 情况下,jQuery 必须遍历到顶部,如果只是为了验证那里无事可做。在任何情况下,影响都可以忽略不计。向上遍历很快,因为一个元素只有这么多的父元素。 .on() 可以直接绑定(如果选择器被省略或为空),或者如果指定了选择器,则以委托方式绑定。我更喜欢使用 .delegate() 因为意图很明确。无论哪种方式,委托(使用 .on() 或 .delegate())到触发元素的 DOM 中最近的父级将导致更少的冒泡步骤,处理程序,并附加更少的处理程序。请参阅jQuery documentation 中的“直接和委托事件”部分 “将 ... 委托给最近的父级 ... 附加更少的处理程序” - 绝对不是。我确信$(document).on 总是将事件处理程序准确地附加到一个元素上,从不超过一个。另一方面,如果父选择器选择了多个元素,则同一个处理程序会附加到多个元素。当然,除非您有数百个元素,否则最好尽可能靠近。 @JanDvorak :请阅读 .on() jQuery Documentation 的“直接和委托事件”的代码示例周围的文本如果您要 $("#dataTable tbody tr").on("click ", function() ... 在具有 1000 行的表上,将附加 1000 个处理程序。但是,使用 .delegate() 或 .on() 如下: $( "#dataTable tbody" ).on( "click", "tr", function() ... "仅将事件处理程序附加到一个元素,即 tbody,并且事件只需要冒泡一层(从单击的 tr 到 tbody)"(引用jQuery 文档)。

以上是关于是否无法为 $(document) 上的 jqueryui/jqm 小部件事件设置 on() 侦听器?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 document.cookie 删除 Chrome 上的特定 cookie [重复]

循环遍历 jQuery 函数中的值

Phonegap-iOS 防止 iCloud 上的 Documents 文件夹备份

jQuery库

Windows 上的 Git Bash - 致命:无法创建“C:/Users/scharko00/Documents/GitHub/myProject/.git/index.lock”:没有这样的文件

jsjquery - DOM操作