这是看Railscasts 229 Polling For Changes时想到的一个问题,就是Rails的Unobtrusive Javascript如何去为一个不存在于DOM树中的对象去绑定事件。
举个例子:
我有一个列表,就是用Rails的scaffold生成的那种,每行显示一个产品信息,后面有三个按钮(显示,编辑,和删除),整个列表用 table 标签,每一行用 tr 标签。以下是一行的例子。为了方便我只写了Delete按钮,因为只有它才绑定了JS。
<tr class="product">
<td>iPhone</td>
<td>
<a rel="nofollow" data-method="delete" data-confirm="Are you sure?" href="/products/1">Destroy</a>
</td>
</tr>
我们知道Unobtrusive Javascript的做法,是在整个页面加载之前,搜索DOM树,然后为特定的标签去绑定Javascript函数。比如上面的html中的 a 标签,它有 data-confirm 属性,Rails的Unobtrusive Javascript会为它绑定特定的函数,让我们点击这个按钮时,弹出 “Are you sure ?” 的提示信息。
现在设想一种情况,我们用Ajax来实时更新这个列表,比如每隔几秒钟去读一下,然后把新的product增量添加到列表的最下面。这时,因为新增加的那一列是在页面加载完成之后才添加进DOM树的,按道理这时是不会为新那一列的Delete按钮绑定事件的。但实际上,Rails很好的处理了这种情况,无论是通过什么方法去修改或替换DOM节点,那些特殊节点的事件都会正确执行。
于是我想知道Rails是如何处理事件绑定的,因为我那个Railscast的例子中用的 jquery-rails 这个gem,所以我查看了它提供的rails.js文件。发现它处理 data-confirm 的。
$('a[data-confirm],input[data-confirm]').live('click', function () {
var el = $(this);
if (el.triggerAndReturn('confirm')) {
if (!confirm(el.attr('data-confirm'))) {
return false;
}
}
});
这里它是用 live 方法来为找到的DOM节点(实际上应该叫jQuery包装集)绑定事件的。再去查查 jQuery的文档,发现它对 live 方法的描述如下:
Attach a handler to the event for all elements which match the current selector, now or in the future.
大概意思是说,live 方法可以为选择器找到的对象绑定事件处理函数,不管这个对象是已有的,还是以后要添加进来的。
关于如何做到这点,jQuery的文档中也有详细的介绍,大致就是:jQuery并不是把Javascript函数绑定到选择器查找出来的节点,而是绑定到html文档的根节点。当我们触发子节点的事件后,通过事件冒泡,来调用绑定到根节点上的Javascript函数。有兴趣的可以看看jQuery的文档说明,说得还是很详细的。
因为我原来写过一个基于Prototype的JS列表,用处和上面说的差不多。而我当时没找到Prototype有类似jQuery的live函数。所以我又看了下Prototype版本的 rails.js 文件。发现Prototype是这样处理的:
document.on("click", "*[data-confirm]", function(event, element) {
var message = element.readAttribute('data-confirm');
if (!confirm(message)) event.stop();
});
Prototype是用 on 方法来处理的,原理和jQuery差不多,就不多说了。有兴趣的可以看看Prototype的文档说明(这个就太简洁了)。不过从语法可以比较明显的看到,函数是直接绑定给document节点的。相对而言,我更喜欢 jQuery 的API风格,这点就见仁见智了。
分享到:
相关推荐
Unobtrusive JavaScript date-picker widgit汉化版,date-picker汉化版
萤火虫UJS Firebug 扩展,用于显示绑定到 DOM 元素的 Unobtrusive Javascript。 more documentation coming soon
JS超级名著《Essentials of Javascript》目录: JavaScript 1 JavaScript syntax 18 JavaScript Style Sheets 43 JavaScript engine 44 ...Unobtrusive JavaScript 136 Venkman 139 XMLHttpRequest 141
微软的jquery.validate.unobtrusive.js验证插件,可以用来验证单选和多选框的.
Part II explains the scripting environment provided by web browsers, with a focus on DOM scripting with unobtrusive JavaScript. The broad and deep coverage of client-side JavaScript is illustrated ...
本书还包括详细的参考手册,涵盖了JavaScript的核心API、遗留的客户端API和W3C标准DOM API,记述了这些API中的每一个JavaScript对象、方法、性质、构造函数、常量和事件处理程序。 这本最畅销的JavaScript参考书的第...
jquery.validate.unobtrusive.min.js 文件很小,加载速度快 jQuery验证控件
but their usage should be clear enough, allowing you to skip that part if you already have a solid understanding of programming JavaScript, including topics such as unobtrusive JavaScript and feature...
Part II explains the scripting environment provided by web browsers, with a focus on DOM scripting with unobtrusive JavaScript. The broad and deep coverage of client-side JavaScript is illustrated ...
jquery.unobtrusive-ajax.min.js
<script src="./js/jquery.validate.unobtrusive.js"> 请输入名字!" data-val-required="请输入名字!" data-val="true"/> ...
前端项目-jquery-validation-unobtrusive,添加到jquery validation,以在data-*属性中启用不显眼的验证选项。
jquery.unobtrusive-ajax 一个Ajax 异步刷新的脚本 具体方法在我的主页,大家可以看一下,如有疑问,欢迎留言
jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求。
Unobtrusive Ajax is about making web applications that work for everyone all the time, even if you have JavaScript turned off, or you're using a mobile phone or a screen reader, or however you happen ...
jquery-ajax-unobtrusive, 在数据 * 属性中,添加到 jQuery Ajax以启用低调选项 jQuery低调 AjaxjQuery低调Ajax库补充了 jQuery Ajax方法,添加了对通过Ajax调用指定HTML替换选项的支持,如 HTML5 data-* 元素。...
Unobtrusive DOM 脚本编程的主要方面,包括一个关于文档对象模型,事件,JavaScript 与CSS 交互的简短的总览。最后你看到了Ajax 背后的前提和在现代浏览器中JavaScript 的支持。这些话题加在一起,足够带你步入专业...