jQuery的.on()方法详解

#  为了看阳光,好好学习

## 主要是翻译了jQuery官方文档的.on()方法的英文api

(http://api.jquery.com/on/)

.on( events [, selector] [, data] , handler(eventObject) )

1.概述:绑定一个或多个事件的event handler function到选中的元素上。

2.参数:

.on( events [, selector] [, data], handler(eventObject) )

      event一个或多个空格分隔的事件类型和可选的命名空间,如“click”或“keydown.myPlugin”。

      selector:过滤那些触发事件的被选中元素的后代元素(selector匹配的后代元素才能触发)。如果选择器是null或 者被省略,则选中元素总能触发事件。

      data:当事件被触发时,data通过event.data传递给事件处理函数。 

      handler(eventObject):事件被触发时用来处理的函数。如果一个函数只是简单地返回false,则可以使用值false(The value false is also allowed as a shorthand for a function that simply does return false.),(就是说handler这个参数可以使用false来代替一个只返回false值的函数,对吧)

.on( events-map [, selector] [, data] )

        events-map:{}名值对;名是一个或多个空格分隔的事件类型和可选的命名空间,值为事件被触发时用来处理的函数。

        selector:同上。

        data:同上。

3.

.on()方法绑定event handlers到当前选中的元素。从JQuery 1.7开始,.on()方法提供了绑定event handlers所需的所有功能(是click等事件的基础函数)。为了帮助从旧版本的JQuery事件处理方法转变到新的处理方法中,请查看.bind(), .delegate(), and .live()。使用.on()移除事件,请查看.off()。绑定只运行一次就被移除的事件,请查看.one()。

4.Event names and namespaces

任何事件名称都可以用作事件参数。jQuery将遍历浏览器标准的JavaScript对象类型,当用户行为,如click等触发浏览器事件时,handler function将被执行。除此之外, .trigger() 方法既可以触发标准的浏览器事件,也可以触发自定义的事件。

事件名称,可以是合格的事件命名空间,事件命名空间简化了移除或者触发事件。例如,"click.myPlugin.simple"为click这一特殊事件定义了myPlugin和simple两个命名空间。click事件绑定的处理函数可以这样.off("click.myPlugin") or .off("click.simple")来移除,而不需要打扰其它的click事件处理函数。命名空间和css的classes是相似的,他们都不分层;只有一个名字需要匹配。以下划线开始的命名空间保留给jQuery使用。

在另一种形式的.on()方法中,events-map参数是一个JavaScript对象,或“map”。keys是个或多个空格分隔的事件类型和可选的命名空间。value是事件被触发时用来处理的函数(或者false)。在其它方面,两者是相同的。

5.Direct and delegated events

绝大多数的浏览器事件泡或传播,都从文档最深的元素(目标元素)开始向上传播到文档根节点。在IE8以及更低版本的IE中,少部分事件如change,submit不是原生的冒泡传播,但是jQuery修复了他们使他们也冒泡传播,创造了一致的跨浏览器行为。

如果selector省略或是空的,event handler将被称作direct or directly-bound。每次当事件发生在选中元素上时,事件处理函数将被调用,而不管它是直接发生在选中元素上还是从一个后代元素冒泡而来。

当selector被提供,event handler将被称作是delegated(委派)。当事件直接发生在选中元素上时,handler将不被调用,只有当事件发生在匹配selector的后代元素上时handler才会被调用。jQuery冒泡传播从事件target到绑定着事件处理函数的元素(从里到外),并且在这条路径上的任何元素匹配selector(可能有多个),handler将执行。

event handler只被绑定到当前选中的元素;在你的代码中调用.on()的时候它们必须存在与网页中。为了确保元素是存在并且可以选择的,请为元素执行ready handler。如果新的HTML被添加到页面中,必须在新的HTML被放置到页面中后选择元素和绑定事件处理函数。或者,使用delegated事件来绑定事件处理函数。

Delegated events的优势是,他们可以从子元素来处理事件,这些子元素是在稍后的时间被添加。通过选择一个在此刻确保存在的元素,delegated  event handler可以被绑定,这样可以避免频繁地绑定和移除event handlers。这个元素可以是MVC设计模式中的view容器元素,例如document,如果事件处理函数要监视文档中所有的冒泡事件的话。文档根元素是在载入任何其它HTML之前就可用的,所以它是安全的绑定事件方法,而不必等待文档ready。

除了在未创建的后代元素上绑定事件处理函数外,delegated的另外一个好处就是当许多事件需要被监听时,有着较低的开销。在一个1000行的数据表中,这个例子将绑定一个handler给1000个元素。

$("#dataTable tbody tr").on("click", function(event){
	alert($(this).text());
});

delegated-events方法只绑定一个event handler给一个元素,tbody,事件只需要向上冒泡一级(from the clicked tr to tbody):

$("#dataTable tbody").on("click", "tr", function(event){
	alert($(this).text());
});

6.The event handler and its environment

handler参数是一个函数(或者是false),并且是必须的除非是events-map这种形式的参数。你可以提供一个匿名的回调函数,或者如下例所示,声明一个具名函数并且传入它的名字。

function notify() { alert("clicked"); }
$("button").on("click", notify);

当浏览器触发一个事件或者其它的JavaScript调用jQuery's .trigger() 方法来触发,jQuery传递给回调函数一个event对象,它可以用来分析和改变事件的状态。事件对象包括了一组格式化的浏览器提供的数据子集;浏览器的未改进的原生事件对象可以用event.originalEvent来访问。例如event.type包含事件的名称(例如,“resize”)和event.target表示事件发生的最深(内)的元素。

默认情况下,大多数事件从原来的事件目标冒泡到文档根元素。在冒泡路上的每个元素,jQuery执行任何匹配被绑定的事件处理函数。handler可以通过调用event.stopPropagation()阻止事件在文档树上的冒泡(也阻止了这些元素上的handlers运行)。然而不管怎样,其它被绑定在当前元素上的handlers仍将运行。为了阻止这种情况,可以调用event.stopImmediatePropagation().(绑定在一个元素上的事件处理函数以他们被绑定的顺序执行)

同样,handler可以调用event.preventDefault() 来取消浏览器默认行为;例如,点击事件的默认行为是follow the link。不是所有的浏览器事件都有默认行为,也不是所有的默认行为都可以取消。请查看W3C Events Specification来获取更多的细节。

事件处理函数返回false将自动调用event.stopPropagation()方法和event.preventDefault()方法。“false”也可以当作一个只返回false值的函数的简写。所以, $("a.disabled").on("click", false),绑定了一个事件处理函数给所有拥有class=“disabled ”的链接,当点击它们时,链接将不会被访问,并且事件也不会冒泡。

当jQuery调用一个handler的时候,this关键字指向事件发生的元素;对于directly bound events,this是绑定事件的元素,对于delegated events,this是selector匹配的元素。(注意:this可能和event.target不一致,如果事件是从一个后代元素冒泡而来)可以使用$(this),来使this(DOM对象)变成jQuery对象,从而可以使用jQuery的一些方法。

7.Passing data to the handler

如果一个不是null或undefined的data参数被提供了的话,它将会被传递给handler通过event.data属性,每次事件被触发时。data参数可以是任何类型的,但是如果是字符串的话,则selector参数也必须被提供或者使用null来来做占位符,为了不被误认为是selector。最好的方式是使用一个对象(map),这样多个值都可以作为属性传进去。

在jQuery 1.4,同样的event handler可以多次绑定给一个元素。当event.data特性被使用的时候,这是非常有用的,或者其它独特的数据驻留在事件处理函数的closure(闭包)中。例如

function greet(event) { alert("Hello "+event.data.name); }
$("button").on("click", { name: "Karl" }, greet);
$("button").on("click", { name: "Addy" }, greet);

当按钮被点击的时候,上面的代码将产生两个不同的alerts。

data参数是作为一种补充添加在.on()方法上的,你也可以在trigger或者triggerHandler使用第二个参数传递数据给一个event handler。

(原句:

As an alternative or in addition to the data argument provided to the .on() method, you can also pass data to an event handler using a second argument to .trigger() or .triggerHandler().

8.Event Performance

在大多数情况下,诸如click这种事件很少发生,所以performance(性能)也是不重要的。然而,像mouseover或者scroll这种高频事件每秒钟可以触发数次, 在这种情况下,明智地使用事件将是很重要的。可以通过减少要做的工作数量来提高性能,缓存信息而不是重新计算,或者使用setTimeout来降低实际页面的更新速率。

在靠近文档树的顶端绑定许多delegated event handlers会降低性能。每次事件发生时,jQuery必须比较所有绑定这种类型的事件的selectors和事件冒泡这条路上的每一个元素,从event.target一直到文档顶端。为了获得更好的性能,绑定delegated events应尽可能靠近事件目标。在大的文档上,要避免过度使用document或者document.body来绑定delegated events。

jQuery可以非常快速地处理 tag#id.class这种形式简单的选择器,当他们被用来过滤delegated events. 所以,"#myForm", "a.external", and "button"都是非常非常快的选择器。使用复杂选择器的Delegated events,特别是使用有等级的选择器,可能会慢好几倍--尽管对于大多数程序他们仍然是非常快的。有等级的选择器,通常可以被避免,绑定handler到更合适的元素上。例如,使用$("#commentForm").on("click", ".addNew", addComment).来代替$("body").on("click", "#commentForm .addNew", addComment)。

9.Additional notes

有一些速记方法,.click(),可以被用来绑定或者触发事件。查找事件分类,来获得一份完整的速记清单。

jQuery 1.8 不赞成这种做法:“hover”被用来当作"mouseenter mouseleave"的速记。它绑定一个单独的handler到两个事件上,而且handler还要检查event.type来决定事件是mouseenter还是mouseleave.别把“hover”这个虚假的事件名称和.hover()这个方法混淆,.hover()接受一个或者两个函数。

jQuery的事件系统要求一个DOM元素允许通过元素的属性绑定data,所以事件可以被监测和触发。object,embed,applet元素不可以绑定data,因此,不可以绑定jQuery事件。

W3C特别说明focus和blur事件不冒泡,但是jQuery定义了跨浏览器的focusin和focusout事件,它们是冒泡的。当focus和blur被用来绑定delegated event handlers,jQuery遍历名称并且用 focusin and focusout来分别代替他们。为了一致和明晰,请使用冒泡事件名称。

jQuery还特别阻止 right(鼠标右键) and middle(滚轮) clicks冒泡,当他们不是发送在被点击元素上时。如果要让middle click 工作,mousedown or mouseup事件应该要用 .on()替代。

在所有的浏览中, load, scroll, and error ((e.g., on an <img> element) )事件都不冒泡。在IE8以及更低版本的IE浏览器中,paste 和 reset事件不冒泡。当使用delegation委托事件时,但是他们可以被使用,这些事件是不被支持的,当他们被直接绑定在触发事件的元素上。

window对象上的error对象使用不标准的参数和返回值,所以它不被jQuery对象所支持。所以,直接绑定handler到window.onerror 。

相关推荐