事件选择器对决
简单挑战:找到两个不同元素(使用它们的 #ID 作为引用)下面的所有 LI 元素,并绑定一个点击处理程序,该处理程序会更改 LI 的文本颜色。以下是您在所有流行的事件/选择器库中执行此操作的方式。
Behaviour + Prototype
Behaviour.register({ '#item li': function(element) { Event.observe(element, 'click', function(event) { Event.element(element).setStyle({color: '#c00'}); }); }, '#otheritem li': function(element) { Event.observe(element, 'click', function(event) { Event.element(element).setStyle({color: '#c00'}); }); } });
Prototype 1.5.0
$$('#item li, #otheritem li').each(function(li){ Event.observe(li, 'click', function(event) { Event.element(li).setStyle({color: '#c00'}); }); });
event:Selectors
EventSelectors.start({ '#item li:click, #otheritem li:click': function(){ this.setStyle({'color': '#c00'}); } });
jQuery
$("#item li, #otheritem li").click(function(){ $(this).css('color', '#c00'); });
我喜欢认为代码本身说明了一切,哪个最容易使用和理解。我发现有趣的是,Prototype 正迁移到更接近 jQuery 的东西,而 jQuery 本身正在推出一些非常酷的新东西。一定要密切关注新版本的发布,它们很快就会推出。
哇,JQ 的解决方案是迄今为止最明显的选择。我最近才开始深入研究它,此前看到了 Cody 最近使用 Thickbox 做了什么。我对它简洁和逻辑的印象非常深刻,并且期待着新版本的发布。
几个快速问题
1. 我找不到可以在命令行使用的 svn url(svn co ...),这是故意的吗?也许你可以提供一个。
2. 是否可以有一个更开放的论坛......一个我不需要订阅的论坛?我收到的电子邮件已经够多了,我只偶尔需要互动,订阅似乎很愚蠢......也许 Google Groups 是一个不错的选择。
3. 下一个版本什么时候发布?我在 svn(web)中看到了一些拖放代码,也许可以写一篇关于预期内容的文章?
4. 这可能适合论坛(见 #2)。有没有办法查询 DOM,并将结果以树的形式而不是数组的形式返回?我有一堆嵌套的 div、表格等,它们代表类似于解析树的东西,我需要从这些树中构建表达式,如果我得到一个扁平化的节点集,这将不容易(不可能?)。
顺便说一句,这看起来真的很酷 :)
嗨,John,
这项工作和 JQuery 本身做得很好。API 很棒。
我有一些关于 JQuery 的建设性意见。我想更多地探索 jQuery,但有一件事让我对它很反感,那就是代码的简洁性。像 a、b、c 这样的变量名没有意义,这使得 jQuery 的代码很难阅读和理解。
我假设这是一个文件大小决定,但我们有压缩工具来处理此类问题。虽然我当然可以阅读 jQuery 文档来解决使用方法,但为了更深入地理解代码本身,我们必须能够阅读它。
另外,关于你所做的选择器方面的内容。我想指出,你也可以使用 event:Selectors 访问事件对象,并且你还可以使用 'this' 关键字访问上下文中的对象。最后,使用 event:Selectors,你可以在每个规则中使用多个事件类型(例如,#item:click, #item2:mouseover: function(e) {} ...)。
嗨,Justin - 很高兴看到你来!
关于变量命名问题的观点很棒。使用短变量名已经成为我代码编写习惯的“根深蒂固”的一部分,我绝对需要改变它。
关于 'this' 关键字的观点很好,我现在已经将你的代码改用它,而不是 'e' 参数。绑定多个事件类型绝对是 event:Selctors 的一大优势,感谢你提到了这一点。
这是你对 jQuery 方法的简洁性的绝佳展示。期待更多......
致敬
Ashutosh
这可能看起来很奇怪,但我同时是 JQuery 和 Prototype/Scriptaculous 的忠实粉丝,但它们之间在 API 上竞争是否有意义?例如,为什么你不为 Prototype 贡献代码,反之亦然?或者,一开始......在 Rails 中包含 JQuery:defaults?我是不是漏掉了什么?这些库开始成为开发中的真正规范,每个人都在寻找解决像这样的简单问题的终极单行代码......无论如何,做得很好!
Jon - 感谢你的反馈!Prototype 和 Scriptaculous 都是很棒的库,包含大量宝贵的优秀代码 - 但它们都有一些 jQuery 没有关注的东西
1) 它们是为特定目的而编写的(例如,Prototype 是为了与 Ruby on Rails 很好地协同工作而编写的,Scriptaculous 是为了很好地实现效果而编写的) - 并且在处理新的输入时非常防御。
2) 它们的功能非常强大(因此,下载文件很大)。
最重要的是,我们希望 jQuery 成为最简单的库,同时仍然具有最大的“影响力”。因此,与其提供几十种晦涩的动画(例如),我们只提供少量动画,但将 API 保持开放,以便将来进行改进/插件开发。
因此,要回答你的问题:我们当然会考虑向 Prototype 和/或 Scriptaculous 提交一些内容 - 但目前,我们主要关注的是保持这个库简洁而美观,并修复出现的所有错误:-)。
我喜欢它!就像 John 所说,示例说明了一切。
嗨,John,
我真正希望看到的是对 :hover 事件的类似比较。
当我找到 JQuery 时,我就不再关注 Prototype 和 Dojo 了(或者至少直到我需要做更重的东西)——所以他们可能也有这个——但我喜欢你对 hover 的实现,它处理了所有嵌套和冒泡......只是有效。
能够仅用 3-4 行代码将 JQuery 应用到Suckerfish Dropdowns(或任何需要 *:hover 才能在 IE 中工作的代码)对我来说是一个胜利,我认为它将再次证明你的观点。
Pingback: La potencia de JQuery » ingeniuz :: desarrollo web útil
Pingback: Event Selector Showdown
这很酷。但值得一提的是:代表 YUI 团队
YAHOO.util.Event.on([YAHOO.util.Dom.get('item').getElementsByTagName('li'),
YAHOO.util.Dom.get('otheritem').getElementsByTagName('li')],
'click',function(){ YAHOO.util.Dom.setStyle(this,'color','#c00'); });};
考虑到 YUI 不是一个事件选择器库,这已经很不错了。yQuery(为了方便起见,称之为查询)与 jQuery 之间唯一的区别是命名空间,在这个特定示例中为“YAHOO.foo.bar”与“$”。哦,还有两个 getElementsByTagName,否则你真的做得很好:) - 我们来做更多挑战,这很有趣。
Pingback: jQuery 赢得事件选择器对决
Pingback: jQuery 赢得事件选择器对决
嗯,我个人更喜欢 event:Selectors,我认为至少 - 它们俩都差不多。
Dustin:关于 YUI…抱歉兄弟,但与 event:Selectors/jQuery 相比,那段代码太糟糕了(即使没有命名空间问题):)
对于未来的版本,如果你能包含一个原始的 JS 版本...以方便与框架为我们带来的奇妙世界进行对比。
Kyle,糟糕透顶?别忘了(就像我说的)Y! 的目标不是改变语言本身...而且它的代码仍然比 Prototype 少(对于这个特定的例子)。是因为我不得不手动写出 getElementsByTagName 吗?天哪,太苛刻了。
@Dustin,无论我如何重新检查你的代码片段,我都会得到一个多余的右花括号和分号(你代码片段的最后两个字符)。我是不是漏了什么?
Joel,我的代码插入确实出错了。它是在其他代码中,我意外地粘贴了多余的两个字符。只需删除最后的“};”。
感谢你澄清这一点 - 我以为我关于 javascript 的知识比实际还要差,因为我当时很困惑。
我喜欢你的作品。
Pingback: Dee’s-Planet! » 事件选择器对决:jQuery 挑战
Pingback: 第 13 集:JavaScript 库概述
Pingback: CODE POETRY » jQuery - 新兴 JavaScript
尝试使用 Prototype 1.5 示例,但一些错误导致它无法使用。以下是修改后的版本,它对我来说有效
$$(‘#item li’,’#otheritem li’).each(function(li){
Event.observe(li, ‘click’, function(event) {
Event.element(event).setStyle({color: ‘#c00’});
});
});
这两个修复
1) 将不同的搜索字符串作为单独的参数添加到 $$ 中
2) 使用 Event.element(event) 代替 Event.element(li)
我认为我更喜欢 eventSelectors。一方面,setStyle 散列表似乎更适合 CSS,因为它们都是键值对。由于没有使用 jQuery,我可能遗漏了一些东西,但设置值的 arguments 数组方法对我来说不太合适。
无意冒犯,但 jQuery 中的事件连接对我来说就像纯粹的邪恶。;-) 设置器应该表明它们是设置器。在前面加上“set”并不必要,但像“click”这样的动词会立即让我联想到一些 DSL 驱动的功能测试框架。它不是在执行动作,所以它不应该表明是。抱歉,如果说得很苛刻...
除此之外,它们都激起了我的兴趣,足以让我决定放弃 Behaviour。它已经为我服务了很久,但也许它的时代已经过去了。
至于 YUI,是的,客户端 JavaScript 都是关于 DOM 操作的,因此 getElementsByTagName 的冗长性和过度的命名空间在这里真的对它不利。
看到针对 YUI 版本的评论,我感到非常惊讶,尽管这可能是因为受众是 pro-jQuery。jQuery 似乎很有趣,但很难争辩说它的代码对于不熟悉该库的人来说是不可读的。$$() 是什么?如果我管理一个项目,我需要在鼓励编写以下代码的库之间进行选择
$(“#item li, #otheritem li”).click(function(){
$(this).css(‘color’, ‘#c00’);
});
以及鼓励编写以下代码的库之间进行选择
YAHOO.util.Event.on([YAHOO.util.Dom.get(‘item’).getElementsByTagName(‘li’),
YAHOO.util.Dom.get(‘otheritem’).getElementsByTagName(‘li’)],
‘click’,function(){ YAHOO.util.Dom.setStyle(this,’color’,’#c00′); });
如果我选择其他任何东西,我会在我的客户/公司身上造成巨大的维护成本。YUI 的冗长性是一个*特性*,它允许它保留在自己的命名空间中。如果你不喜欢它,只需一行代码就可以为任何你喜欢的元素创建别名。区别在于,别名仅在自定义代码(而不是库本身)中使用,并且由用户选择,而不是由库的作者选择。反对 getElementsByTagName 函数名称的长度,并不是反对 YUI。它是 DOM 的一部分 - 语言的一部分。如果你只是为了改变而改变方法的名称,那么你将迫使你的库用户学习你的 JavaScript 版本。这场对决中的不同解决方案,对我来说,仅仅证明了当今的库走向了多么错误的方向。4 种非标准、低可读性的方法来完成可以用标准 JavaScript 或 YUI 中的*实用工具*(而不是语言重写)帮助来完成的事情。
JS 库应该帮助 JavaScript 开发人员。其他任何东西都是自负。
$D = YAHOO.util.Dom;
$E = YAHOO.util.Event;
$E.on([$Dom.get(‘item’).getElementsByTagName(‘li’), $D.get(‘otheritem’).getElementsByTagName(‘li’)],’click’,function(){ $D.setStyle(this,’color’,’#c00′);
});
我认为应该考虑不使用任何库的实现方法作为“控制”。
var tags = {
"item": document.getElementById("item").getElementsByTagName("li"),
"otheritem": document.getElementById("otheritem").getElementsByTagName("li")
}
window.onload = function() {
for (tag in tags) {
tag.onclick = function() {
this.style.color = "#c00";
}
}
}
针对那个说 Yahoo 的代码更易于维护,因为更冗长的人 - 我最近才发现 jQuery。我是一名设计师和 HTML 黑客,我对 JavaScript 不太了解。我总是只是在网上寻找其他人为我的 JS 问题提供的不错的、非侵入性的解决方案 - 这就是我找到 jQuery 的方式。你知道吗?我之前见过其他 JS 框架(Behaviour、event:Selectors、Yahoo!) - 它们对我来说真的没有太大的意义。它们似乎和 JS 一直以来的那种半乱码一样。
但 jQuery 呢?我*明白了*。我立刻就明白了 jQuery 的工作原理,以及如何使用它来做事情。在下载框架并浏览完教程后,我在*十分钟内*就为 jQuery 写了一个(非常简单,我承认)插件!
因此,从一个主要从事艺术创作、Photoshop/HTML/CSS 黑客的角度来看,jQuery 真的很棒。
而且在很多组织中,*我们*最终要负责更新 JavaScript,因为“真正的开发人员”忙于后端工作。因此,一个对*我们*有意义的库对我们来说是一个巨大的帮助!
--Adrienne
Adrienne,
你的观点是你不知道 JavaScript,因此你发现 YUI 很困惑。你说你很容易理解 jQuery,因为它与典型的 JavaScript 不同。这正是我想说的。仅仅因为你不想学习 JavaScript,并不意味着你的 JavaScript 程序员也应该学习 jQuery。
mwarden,
我认为你对 jQuery 和 YUI 的比较过于肤浅。你说只需要一行代码就可以将 YUI 的过度命名空间和冗长代码简化。我则认为,我更愿意使用一个一开始就很简洁、文档完善的库,而不是使用另一个开发人员为了解决 YUI 冗长代码而设计的自己的解决方案。
如果一个库使用起来如此痛苦,以至于你的开发人员最终不得不实现自己的无文档框架(或者只是一些别名集合)来封装它,那么它就不是可维护的。
我知道这是一篇旧文章,但我只是想指出,在 prototype 1.6.0 中,你可以执行以下操作
$$(‘#item li, #otheritem li’).invoke(‘observe’, ‘click’, function() {
$(this).setStyle({color: ‘#c00’});
});