1 module("event", { teardown: moduleTeardown });
3 test("null or undefined handler", function() {
5 // Supports Fixes bug #7229
7 jQuery("#firstp").click(null);
8 ok(true, "Passing a null handler will not throw an exception");
12 jQuery("#firstp").click(undefined);
13 ok(true, "Passing an undefined handler will not throw an exception");
17 test("bind(),live(),delegate() with non-null,defined data", function() {
21 var handler = function( event, data ) {
22 equal( data, 0, "non-null, defined data (zero) is correctly passed" );
25 jQuery("#foo").bind("foo", handler);
26 jQuery("#foo").live("foo", handler);
27 jQuery("div").delegate("#foo", "foo", handler);
29 jQuery("#foo").trigger("foo", 0);
31 jQuery("#foo").unbind("foo", handler);
32 jQuery("#foo").die("foo", handler);
33 jQuery("div").undelegate("#foo", "foo");
37 test("Handler changes and .trigger() order", function() {
41 '<div><div><p><span><b class="a">b</b></span></p></div></div>'
46 .find( "*" ).andSelf().on( "click", function( e ) {
47 path += this.nodeName.toLowerCase() + " ";
49 .filter( "b" ).on( "click", function( e ) {
50 // Removing span should not stop propagation to original parents
51 if ( e.target === this ) {
52 jQuery(this).parent().remove();
56 markup.find( "b" ).trigger( "click" );
58 equals( path, "b p div div ", "Delivered all events" );
63 test("bind(), with data", function() {
65 var handler = function(event) {
66 ok( event.data, "bind() with data, check passed data exists" );
67 equals( event.data.foo, "bar", "bind() with data, Check value of passed data" );
69 jQuery("#firstp").bind("click", {foo: "bar"}, handler).click().unbind("click", handler);
71 ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
73 var test = function(){};
74 var handler2 = function(event) {
75 equals( event.data, test, "bind() with function data, Check value of passed data" );
77 jQuery("#firstp").bind("click", test, handler2).click().unbind("click", handler2);
80 test("click(), with data", function() {
82 var handler = function(event) {
83 ok( event.data, "bind() with data, check passed data exists" );
84 equals( event.data.foo, "bar", "bind() with data, Check value of passed data" );
86 jQuery("#firstp").click({foo: "bar"}, handler).click().unbind("click", handler);
88 ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
91 test("bind(), with data, trigger with data", function() {
93 var handler = function(event, data) {
94 ok( event.data, "check passed data exists" );
95 equals( event.data.foo, "bar", "Check value of passed data" );
96 ok( data, "Check trigger data" );
97 equals( data.bar, "foo", "Check value of trigger data" );
99 jQuery("#firstp").bind("click", {foo: "bar"}, handler).trigger("click", [{bar: "foo"}]).unbind("click", handler);
102 test("bind(), multiple events at once", function() {
104 var clickCounter = 0,
105 mouseoverCounter = 0;
106 var handler = function(event) {
107 if (event.type == "click")
109 else if (event.type == "mouseover")
110 mouseoverCounter += 1;
112 jQuery("#firstp").bind("click mouseover", handler).trigger("click").trigger("mouseover");
113 equals( clickCounter, 1, "bind() with multiple events at once" );
114 equals( mouseoverCounter, 1, "bind() with multiple events at once" );
117 test("bind(), five events at once", function() {
121 handler = function(event) {
125 jQuery("#firstp").bind("click mouseover foo bar baz", handler)
126 .trigger("click").trigger("mouseover")
127 .trigger("foo").trigger("bar")
130 equals( count, 5, "bind() five events at once" );
133 test("bind(), multiple events at once and namespaces", function() {
138 var div = jQuery("<div/>").bind("focusin.a", function(e) {
139 equals( e.type, cur, "Verify right single event was fired." );
143 div.trigger("focusin.a");
145 // manually clean up detached elements
148 div = jQuery("<div/>").bind("click mouseover", obj, function(e) {
149 equals( e.type, cur, "Verify right multi event was fired." );
150 equals( e.data, obj, "Make sure the data came in correctly." );
154 div.trigger("click");
157 div.trigger("mouseover");
159 // manually clean up detached elements
162 div = jQuery("<div/>").bind("focusin.a focusout.b", function(e) {
163 equals( e.type, cur, "Verify right multi event was fired." );
167 div.trigger("focusin.a");
170 div.trigger("focusout.b");
172 // manually clean up detached elements
176 test("bind(), namespace with special add", function() {
179 var div = jQuery("<div/>").bind("test", function(e) {
180 ok( true, "Test event fired." );
185 jQuery.event.special.test = {
186 _default: function(e, data) {
187 equals( this, document, "Make sure we're at the top of the chain." );
188 equals( e.type, "test", "And that we're still dealing with a test event." );
189 equals( e.target, div[0], "And that the target is correct." );
190 ok( data !== undefined , "And that trigger data was passed." );
193 teardown: function(){
194 ok(true, "Teardown called.");
196 add: function( handleObj ) {
197 var handler = handleObj.handler;
198 handleObj.handler = function(e) {
200 handler.apply( this, arguments );
204 ok(true, "Remove called.");
208 div.bind("test.a", {x: 1}, function(e) {
209 ok( !!e.xyz, "Make sure that the data is getting passed through." );
210 equals( e.data.x, 1, "Make sure data is attached properly." );
213 div.bind("test.b", {x: 2}, function(e) {
214 ok( !!e.xyz, "Make sure that the data is getting passed through." );
215 equals( e.data.x, 2, "Make sure data is attached properly." );
219 div.trigger("test", 33.33);
222 div.trigger("test.a", "George Harrison");
225 div.trigger("test.b", { year: 1982 });
230 div = jQuery("<div/>").bind("test", function(e) {
231 ok( true, "Test event fired." );
235 div.appendTo("#qunit-fixture").remove();
237 delete jQuery.event.special.test;
240 test("bind(), no data", function() {
242 var handler = function(event) {
243 ok ( !event.data, "Check that no data is added to the event object" );
245 jQuery("#firstp").bind("click", handler).trigger("click");
248 test("bind/one/unbind(Object)", function(){
251 var clickCounter = 0, mouseoverCounter = 0;
252 function handler(event) {
253 if (event.type == "click")
255 else if (event.type == "mouseover")
259 function handlerWithData(event) {
260 if (event.type == "click")
261 clickCounter += event.data;
262 else if (event.type == "mouseover")
263 mouseoverCounter += event.data;
267 $elem.trigger("click").trigger("mouseover");
270 var $elem = jQuery("#firstp")
278 click:handlerWithData,
279 mouseover:handlerWithData
284 equals( clickCounter, 3, "bind(Object)" );
285 equals( mouseoverCounter, 3, "bind(Object)" );
288 equals( clickCounter, 4, "bind(Object)" );
289 equals( mouseoverCounter, 4, "bind(Object)" );
291 jQuery("#firstp").unbind({
297 equals( clickCounter, 4, "bind(Object)" );
298 equals( mouseoverCounter, 4, "bind(Object)" );
301 test("live/die(Object), delegate/undelegate(String, Object)", function() {
304 var clickCounter = 0, mouseoverCounter = 0,
305 $p = jQuery("#firstp"), $a = $p.find("a:first");
308 click: function( event ) {
309 clickCounter += ( event.data || 1 );
311 mouseover: function( event ) {
312 mouseoverCounter += ( event.data || 1 );
317 $a.trigger("click").trigger("mouseover");
321 $p.delegate( "a", events, 2 );
324 equals( clickCounter, 3, "live/delegate" );
325 equals( mouseoverCounter, 3, "live/delegate" );
327 $p.undelegate( "a", events );
330 equals( clickCounter, 4, "undelegate" );
331 equals( mouseoverCounter, 4, "undelegate" );
336 equals( clickCounter, 4, "die" );
337 equals( mouseoverCounter, 4, "die" );
340 test("live/delegate immediate propagation", function() {
343 var $p = jQuery("#firstp"), $a = $p.find("a:first"), lastClick;
346 $a.live( "click", function(e) {
347 lastClick = "click1";
348 e.stopImmediatePropagation();
350 $a.live( "click", function(e) {
351 lastClick = "click2";
353 $a.trigger( "click" );
354 equals( lastClick, "click1", "live stopImmediatePropagation" );
358 $p.delegate( "a", "click", function(e) {
359 lastClick = "click1";
360 e.stopImmediatePropagation();
362 $p.delegate( "a", "click", function(e) {
363 lastClick = "click2";
365 $a.trigger( "click" );
366 equals( lastClick, "click1", "delegate stopImmediatePropagation" );
367 $p.undelegate( "click" );
370 test("bind/delegate bubbling, isDefaultPrevented", function() {
372 var $anchor2 = jQuery( "#anchor2" ),
373 $main = jQuery( "#qunit-fixture" ),
374 fakeClick = function($jq) {
375 // Use a native click so we don't get jQuery simulated bubbling
376 if ( document.createEvent ) {
377 var e = document.createEvent( "MouseEvents" );
378 e.initEvent( "click", true, true );
379 $jq[0].dispatchEvent(e);
381 else if ( $jq[0].click ) {
382 $jq[0].click(); // IE
385 $anchor2.click(function(e) {
388 $main.delegate("#foo", "click", function(e) {
389 var orig = e.originalEvent;
391 if ( typeof(orig.defaultPrevented) === "boolean" || typeof(orig.returnValue) === "boolean" || orig.getPreventDefault ) {
392 equals( e.isDefaultPrevented(), true, "isDefaultPrevented true passed to bubbled event" );
395 // Opera < 11 doesn't implement any interface we can use, so give it a pass
396 ok( true, "isDefaultPrevented not supported by this browser, test skipped" );
399 fakeClick( $anchor2 );
400 $anchor2.unbind( "click" );
401 $main.undelegate( "click" );
402 $anchor2.click(function(e) {
403 // Let the default action occur
405 $main.delegate("#foo", "click", function(e) {
406 equals( e.isDefaultPrevented(), false, "isDefaultPrevented false passed to bubbled event" );
408 fakeClick( $anchor2 );
409 $anchor2.unbind( "click" );
410 $main.undelegate( "click" );
413 test("bind(), iframes", function() {
414 // events don't work with iframes, see #939 - this test fails in IE because of contentDocument
415 var doc = jQuery("#loadediframe").contents();
417 jQuery("div", doc).bind("click", function() {
418 ok( true, "Binding to element inside iframe" );
419 }).click().unbind("click");
422 test("bind(), trigger change on select", function() {
425 function selectOnChange(event) {
426 equals( event.data, counter++, "Event.data is not a global event object" );
428 jQuery("#form select").each(function(i){
429 jQuery(this).bind("change", i, selectOnChange);
430 }).trigger("change");
433 test("bind(), namespaced events, cloned events", 18, function() {
434 var firstp = jQuery( "#firstp" );
436 firstp.bind("custom.test",function(e){
437 ok(false, "Custom event triggered");
440 firstp.bind("click",function(e){
441 ok(true, "Normal click triggered");
442 equal( e.type + e.namespace, "click", "Check that only click events trigger this fn" );
445 firstp.bind("click.test",function(e){
447 ok( true, "Namespaced click triggered" );
451 equal( e.type + e.namespace, check, "Check that only click/click.test events trigger this fn" );
454 //clone(true) element to verify events are cloned correctly
455 firstp = firstp.add( firstp.clone( true ).attr( "id", "firstp2" ).insertBefore( firstp ) );
457 // Trigger both bound fn (8)
458 firstp.trigger("click");
460 // Trigger one bound fn (4)
461 firstp.trigger("click.test");
463 // Remove only the one fn
464 firstp.unbind("click.test");
466 // Trigger the remaining fn (4)
467 firstp.trigger("click");
469 // Remove the remaining namespaced fn
470 firstp.unbind(".test");
472 // Try triggering the custom event (0)
473 firstp.trigger("custom");
475 // using contents will get comments regular, text, and comment nodes
476 jQuery("#nonnodes").contents().bind("tester", function () {
477 equals(this.nodeType, 1, "Check node,textnode,comment bind just does real nodes" );
478 }).trigger("tester");
480 // Make sure events stick with appendTo'd elements (which are cloned) #2027
481 jQuery("<a href='#fail' class='test'>test</a>").click(function(){ return false; }).appendTo("#qunit-fixture");
482 ok( jQuery("a.test:first").triggerHandler("click") === false, "Handler is bound to appendTo'd elements" );
485 test("bind(), multi-namespaced events", function() {
497 function check(name, msg){
498 same(name, order.shift(), msg);
501 jQuery("#firstp").bind("custom.test",function(e){
502 check("custom.test", "Custom event triggered");
505 jQuery("#firstp").bind("custom.test2",function(e){
506 check("custom.test2", "Custom event triggered");
509 jQuery("#firstp").bind("click.test",function(e){
510 check("click.test", "Normal click triggered");
513 jQuery("#firstp").bind("click.test.abc",function(e){
514 check("click.test.abc", "Namespaced click triggered");
517 // Those would not trigger/unbind (#5303)
518 jQuery("#firstp").trigger("click.a.test");
519 jQuery("#firstp").unbind("click.a.test");
521 // Trigger both bound fn (1)
522 jQuery("#firstp").trigger("click.test.abc");
524 // Trigger one bound fn (1)
525 jQuery("#firstp").trigger("click.abc");
527 // Trigger two bound fn (2)
528 jQuery("#firstp").trigger("click.test");
530 // Remove only the one fn
531 jQuery("#firstp").unbind("click.abc");
533 // Trigger the remaining fn (1)
534 jQuery("#firstp").trigger("click");
536 // Remove the remaining fn
537 jQuery("#firstp").unbind(".test");
539 // Trigger the remaining fn (1)
540 jQuery("#firstp").trigger("custom");
543 test("bind(), with same function", function() {
546 var count = 0, func = function(){
550 jQuery("#liveHandlerOrder").bind("foo.bar", func).bind("foo.zar", func);
551 jQuery("#liveHandlerOrder").trigger("foo.bar");
553 equals(count, 1, "Verify binding function with multiple namespaces." );
555 jQuery("#liveHandlerOrder").unbind("foo.bar", func).unbind("foo.zar", func);
556 jQuery("#liveHandlerOrder").trigger("foo.bar");
558 equals(count, 1, "Verify that removing events still work." );
561 test("bind(), make sure order is maintained", function() {
564 var elem = jQuery("#firstp"), log = [], check = [];
566 for ( var i = 0; i < 100; i++ ) (function(i){
567 elem.bind( "click", function(){
574 elem.trigger("click");
576 equals( log.join(","), check.join(","), "Make sure order was maintained." );
578 elem.unbind("click");
581 test("bind(), with different this object", function() {
583 var thisObject = { myThis: true },
584 data = { myData: true },
585 handler1 = function( event ) {
586 equals( this, thisObject, "bind() with different this object" );
588 handler2 = function( event ) {
589 equals( this, thisObject, "bind() with different this object and data" );
590 equals( event.data, data, "bind() with different this object and data" );
594 .bind("click", jQuery.proxy(handler1, thisObject)).click().unbind("click", handler1)
595 .bind("click", data, jQuery.proxy(handler2, thisObject)).click().unbind("click", handler2);
597 ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using different this object and data." );
600 test("bind(name, false), unbind(name, false)", function() {
604 jQuery("#qunit-fixture").bind("click", function(e){ main++; });
605 jQuery("#ap").trigger("click");
606 equals( main, 1, "Verify that the trigger happened correctly." );
609 jQuery("#ap").bind("click", false);
610 jQuery("#ap").trigger("click");
611 equals( main, 0, "Verify that no bubble happened." );
614 jQuery("#ap").unbind("click", false);
615 jQuery("#ap").trigger("click");
616 equals( main, 1, "Verify that the trigger happened correctly." );
618 // manually clean up events from elements outside the fixture
619 jQuery("#qunit-fixture").unbind("click");
622 test("live(name, false), die(name, false)", function() {
626 jQuery("#qunit-fixture").live("click", function(e){ main++; });
627 jQuery("#ap").trigger("click");
628 equals( main, 1, "Verify that the trigger happened correctly." );
631 jQuery("#ap").live("click", false);
632 jQuery("#ap").trigger("click");
633 equals( main, 0, "Verify that no bubble happened." );
636 jQuery("#ap").die("click", false);
637 jQuery("#ap").trigger("click");
638 equals( main, 1, "Verify that the trigger happened correctly." );
639 jQuery("#qunit-fixture").die("click");
642 test("delegate(selector, name, false), undelegate(selector, name, false)", function() {
647 jQuery("#qunit-fixture").delegate("#ap", "click", function(e){ main++; });
648 jQuery("#ap").trigger("click");
649 equals( main, 1, "Verify that the trigger happened correctly." );
652 jQuery("#ap").delegate("#groups", "click", false);
653 jQuery("#groups").trigger("click");
654 equals( main, 0, "Verify that no bubble happened." );
657 jQuery("#ap").undelegate("#groups", "click", false);
658 jQuery("#groups").trigger("click");
659 equals( main, 1, "Verify that the trigger happened correctly." );
660 jQuery("#qunit-fixture").undelegate("#ap", "click");
663 test("bind()/trigger()/unbind() on plain object", function() {
668 // Make sure it doesn't complain when no events are found
669 jQuery(obj).trigger("test");
671 // Make sure it doesn't complain when no events are found
672 jQuery(obj).unbind("test");
676 ok( true, "Custom event run." );
679 ok( true, "Custom submit event run." );
683 var events = jQuery._data(obj, "events");
684 ok( events, "Object has events bound." );
685 equals( obj.events, undefined, "Events object on plain objects is not events" );
686 equals( obj.test, undefined, "Make sure that test event is not on the plain object." );
687 equals( obj.handle, undefined, "Make sure that the event handler is not on the plain object." );
690 jQuery(obj).trigger("test");
691 jQuery(obj).trigger("submit");
693 jQuery(obj).unbind("test");
694 jQuery(obj).unbind("submit");
697 jQuery(obj).trigger("test");
699 // Make sure it doesn't complain when no events are found
700 jQuery(obj).unbind("test");
702 equals( obj && obj[ jQuery.expando ] &&
703 obj[ jQuery.expando ][ jQuery.expando ] &&
704 obj[ jQuery.expando ][ jQuery.expando ].events, undefined, "Make sure events object is removed" );
707 test("unbind(type)", function() {
710 var $elem = jQuery("#firstp"),
714 ok( false, message );
717 message = "unbind passing function";
718 $elem.bind("error1", error).unbind("error1", error).triggerHandler("error1");
720 message = "unbind all from event";
721 $elem.bind("error1", error).unbind("error1").triggerHandler("error1");
723 message = "unbind all";
724 $elem.bind("error1", error).unbind().triggerHandler("error1");
726 message = "unbind many with function";
727 $elem.bind("error1 error2",error)
728 .unbind("error1 error2", error )
729 .trigger("error1").triggerHandler("error2");
731 message = "unbind many"; // #3538
732 $elem.bind("error1 error2", error)
733 .unbind("error1 error2")
734 .trigger("error1").triggerHandler("error2");
736 message = "unbind without a type or handler";
737 $elem.bind("error1 error2.test",error)
739 .trigger("error1").triggerHandler("error2");
741 // Should only unbind the specified function
742 jQuery( document ).bind( "click", function(){
743 ok( true, "called handler after selective removal");
745 var func = function(){ };
747 .bind( "click", func )
748 .unbind( "click", func )
753 test("unbind(eventObject)", function() {
756 var $elem = jQuery("#firstp"),
759 function assert( expected ){
761 $elem.trigger("foo").triggerHandler("bar");
762 equals( num, expected, "Check the right handlers are triggered" );
766 // This handler shouldn't be unbound
767 .bind("foo", function(){
770 .bind("foo", function(e){
775 .bind("bar", function(){
789 test("hover()", function() {
791 handler1 = function( event ) { ++times; },
792 handler2 = function( event ) { ++times; };
795 .hover(handler1, handler2)
796 .mouseenter().mouseleave()
797 .unbind("mouseenter", handler1)
798 .unbind("mouseleave", handler2)
800 .mouseenter().mouseleave()
801 .unbind("mouseenter mouseleave", handler1)
802 .mouseenter().mouseleave();
804 equals( times, 4, "hover handlers fired" );
807 test("mouseover triggers mouseenter", function() {
811 elem = jQuery("<a />");
812 elem.mouseenter(function () {
815 elem.trigger("mouseover");
816 equals(count, 1, "make sure mouseover triggers a mouseenter" );
821 test("withinElement implemented with jQuery.contains()", function() {
825 jQuery("#qunit-fixture").append('<div id="jc-outer"><div id="jc-inner"></div></div>');
827 jQuery("#jc-outer").bind("mouseenter mouseleave", function( event ) {
829 equal( this.id, "jc-outer", this.id + " " + event.type );
831 }).trigger("mouseenter");
833 jQuery("#jc-inner").trigger("mousenter");
835 jQuery("#jc-outer").unbind("mouseenter mouseleave").remove();
836 jQuery("#jc-inner").remove();
840 test("mouseenter, mouseleave don't catch exceptions", function() {
843 var elem = jQuery("#firstp").hover(function() { throw "an Exception"; });
848 equals( e, "an Exception", "mouseenter doesn't catch exceptions" );
854 equals( e, "an Exception", "mouseleave doesn't catch exceptions" );
858 test("trigger() shortcuts", function() {
861 var elem = jQuery("<li><a href='#'>Change location</a></li>").prependTo("#firstUL");
862 elem.find("a").bind("click", function() {
863 var close = jQuery("spanx", this); // same with jQuery(this).find("span");
864 equals( close.length, 0, "Context element does not exist, length must be zero" );
865 ok( !close[0], "Context element does not exist, direct access to element must return undefined" );
869 // manually clean up detached elements
872 jQuery("#check1").click(function() {
873 ok( true, "click event handler for checkbox gets fired twice, see #815" );
877 jQuery("#firstp")[0].onclick = function(event) {
880 jQuery("#firstp").click();
881 equals( counter, 1, "Check that click, triggers onclick event handler also" );
883 var clickCounter = 0;
884 jQuery("#simon1")[0].onclick = function(event) {
887 jQuery("#simon1").click();
888 equals( clickCounter, 1, "Check that click, triggers onclick event handler on an a tag also" );
890 elem = jQuery("<img />").load(function(){
891 ok( true, "Trigger the load event, using the shortcut .load() (#2819)");
894 // manually clean up detached elements
897 // test that special handlers do not blow up with VML elements (#7071)
898 jQuery('<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />').appendTo('head');
899 jQuery('<v:oval id="oval" style="width:100pt;height:75pt;" fillcolor="red"> </v:oval>').appendTo('#form');
900 jQuery("#oval").click().keydown();
903 test("trigger() bubbling", function() {
906 var win = 0, doc = 0, html = 0, body = 0, main = 0, ap = 0;
908 jQuery(window).bind("click", function(e){ win++; });
909 jQuery(document).bind("click", function(e){ if ( e.target !== document) { doc++; } });
910 jQuery("html").bind("click", function(e){ html++; });
911 jQuery("body").bind("click", function(e){ body++; });
912 jQuery("#qunit-fixture").bind("click", function(e){ main++; });
913 jQuery("#ap").bind("click", function(){ ap++; return false; });
915 jQuery("html").trigger("click");
916 equals( win, 1, "HTML bubble" );
917 equals( doc, 1, "HTML bubble" );
918 equals( html, 1, "HTML bubble" );
920 jQuery("body").trigger("click");
921 equals( win, 2, "Body bubble" );
922 equals( doc, 2, "Body bubble" );
923 equals( html, 2, "Body bubble" );
924 equals( body, 1, "Body bubble" );
926 jQuery("#qunit-fixture").trigger("click");
927 equals( win, 3, "Main bubble" );
928 equals( doc, 3, "Main bubble" );
929 equals( html, 3, "Main bubble" );
930 equals( body, 2, "Main bubble" );
931 equals( main, 1, "Main bubble" );
933 jQuery("#ap").trigger("click");
934 equals( doc, 3, "ap bubble" );
935 equals( html, 3, "ap bubble" );
936 equals( body, 2, "ap bubble" );
937 equals( main, 1, "ap bubble" );
938 equals( ap, 1, "ap bubble" );
940 // manually clean up events from elements outside the fixture
941 jQuery(document).unbind("click");
942 jQuery("html, body, #qunit-fixture").unbind("click");
945 test("trigger(type, [data], [fn])", function() {
948 var handler = function(event, a, b, c) {
949 equals( event.type, "click", "check passed data" );
950 equals( a, 1, "check passed data" );
951 equals( b, "2", "check passed data" );
952 equals( c, "abc", "check passed data" );
956 var $elem = jQuery("#firstp");
958 // Simulate a "native" click
959 $elem[0].click = function(){
960 ok( true, "Native call was triggered" );
964 $elem.live('mouseenter', function(){
965 ok( true, 'Trigger mouseenter bound by live' );
968 $elem.live('mouseleave', function(){
969 ok( true, 'Trigger mouseleave bound by live' );
972 $elem.trigger('mouseenter');
974 $elem.trigger('mouseleave');
976 $elem.die('mouseenter');
978 $elem.die('mouseleave');
980 // Triggers handlrs and native
982 $elem.bind("click", handler).trigger("click", [1, "2", "abc"]);
984 // Simulate a "native" click
985 $elem[0].click = function(){
986 ok( false, "Native call was triggered" );
989 // Trigger only the handlers (no native)
991 equals( $elem.triggerHandler("click", [1, "2", "abc"]), "test", "Verify handler response" );
995 jQuery("#form input:first").hide().trigger("focus");
999 ok( pass, "Trigger focus on hidden element" );
1003 jQuery("#qunit-fixture table:first").bind("test:test", function(){}).trigger("test:test");
1007 ok( pass, "Trigger on a table with a colon in the even type, see #3533" );
1009 var form = jQuery("<form action=''></form>").appendTo("body");
1011 // Make sure it can be prevented locally
1012 form.submit(function(){
1013 ok( true, "Local bind still works." );
1018 form.trigger("submit");
1020 form.unbind("submit");
1022 jQuery(document).submit(function(){
1023 ok( true, "Make sure bubble works up to document." );
1028 form.trigger("submit");
1030 jQuery(document).unbind("submit");
1035 test("trigger(eventObject, [data], [fn])", function() {
1038 var $parent = jQuery("<div id='par' />").hide().appendTo("body"),
1039 $child = jQuery("<p id='child'>foo</p>").appendTo( $parent );
1041 var event = jQuery.Event("noNew");
1042 ok( event != window, "Instantiate jQuery.Event without the 'new' keyword" );
1043 equals( event.type, "noNew", "Verify its type" );
1045 equals( event.isDefaultPrevented(), false, "Verify isDefaultPrevented" );
1046 equals( event.isPropagationStopped(), false, "Verify isPropagationStopped" );
1047 equals( event.isImmediatePropagationStopped(), false, "Verify isImmediatePropagationStopped" );
1049 event.preventDefault();
1050 equals( event.isDefaultPrevented(), true, "Verify isDefaultPrevented" );
1051 event.stopPropagation();
1052 equals( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
1054 event.isPropagationStopped = function(){ return false };
1055 event.stopImmediatePropagation();
1056 equals( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
1057 equals( event.isImmediatePropagationStopped(), true, "Verify isPropagationStopped" );
1059 $parent.bind("foo",function(e){
1061 equals( e.type, "foo", "Verify event type when passed passing an event object" );
1062 equals( e.target.id, "child", "Verify event.target when passed passing an event object" );
1063 equals( e.currentTarget.id, "par", "Verify event.currentTarget when passed passing an event object" );
1064 equals( e.secret, "boo!", "Verify event object's custom attribute when passed passing an event object" );
1067 // test with an event object
1068 event = new jQuery.Event("foo");
1069 event.secret = "boo!";
1070 $child.trigger(event);
1072 // test with a literal object
1073 $child.trigger({type: "foo", secret: "boo!"});
1078 ok( false, "This assertion shouldn't be reached");
1081 $parent.bind("foo", error );
1083 $child.bind("foo",function(e, a, b, c ){
1084 equals( arguments.length, 4, "Check arguments length");
1085 equals( a, 1, "Check first custom argument");
1086 equals( b, 2, "Check second custom argument");
1087 equals( c, 3, "Check third custom argument");
1089 equals( e.isDefaultPrevented(), false, "Verify isDefaultPrevented" );
1090 equals( e.isPropagationStopped(), false, "Verify isPropagationStopped" );
1091 equals( e.isImmediatePropagationStopped(), false, "Verify isImmediatePropagationStopped" );
1093 // Skips both errors
1094 e.stopImmediatePropagation();
1099 // We should add this back in when we want to test the order
1100 // in which event handlers are iterated.
1101 //$child.bind("foo", error );
1103 event = new jQuery.Event("foo");
1104 $child.trigger( event, [1,2,3] ).unbind();
1105 equals( event.result, "result", "Check event.result attribute");
1107 // Will error if it bubbles
1108 $child.triggerHandler("foo");
1111 $parent.unbind().remove();
1114 test(".trigger() bubbling on disconnected elements (#10489)", function() {
1117 jQuery( window ).on( "click", function(){
1118 ok( false, "click fired on window" );
1121 jQuery( "<div><p>hi</p></div>" )
1122 .on( "click", function() {
1123 ok( true, "click fired on div" );
1126 .on( "click", function() {
1127 ok( true, "click fired on p" );
1135 jQuery( window ).off( "click" );
1138 test("jQuery.Event( type, props )", function() {
1142 var event = jQuery.Event( "keydown", { keyCode: 64 }),
1143 handler = function( event ) {
1144 ok( "keyCode" in event, "Special property 'keyCode' exists" );
1145 equal( event.keyCode, 64, "event.keyCode has explicit value '64'" );
1148 // Supports jQuery.Event implementation
1149 equal( event.type, "keydown", "Verify type" );
1151 // ensure "type" in props won't clobber the one set by constructor
1152 equal( jQuery.inArray("type", jQuery.event.props), -1, "'type' property not in props (#10375)" );
1154 ok( "keyCode" in event, "Special 'keyCode' property exists" );
1156 jQuery("body").bind( "keydown", handler ).trigger( event );
1158 jQuery("body").unbind( "keydown" );
1162 test("jQuery.Event.currentTarget", function(){
1165 jQuery('<div><p><button>shiny</button></p></div>')
1166 .on( "click", "p", function( e ){
1167 equals( e.currentTarget, this, "Check delegated currentTarget on event" );
1170 .on( "click", function( e ){
1171 equals( e.currentTarget, this, "Check currentTarget on event" );
1179 test("toggle(Function, Function, ...)", function() {
1183 fn1 = function(e) { count++; },
1184 fn2 = function(e) { count--; },
1185 preventDefault = function(e) { e.preventDefault() },
1186 link = jQuery("#mark");
1187 link.click(preventDefault).click().toggle(fn1, fn2).click().click().click().click().click();
1188 equals( count, 1, "Check for toggle(fn, fn)" );
1190 jQuery("#firstp").toggle(function () {
1191 equals(arguments.length, 4, "toggle correctly passes through additional triggered arguments, see #1701" )
1192 }, function() {}).trigger("click", [ 1, 2, 3 ]);
1195 jQuery("#simon1").one("click", function() {
1196 ok( true, "Execute event only once" );
1197 jQuery(this).toggle(function() {
1198 equals( first++, 0, "toggle(Function,Function) assigned from within one('xxx'), see #1054" );
1200 equals( first, 1, "toggle(Function,Function) assigned from within one('xxx'), see #1054" );
1203 }).click().click().click();
1218 var $div = jQuery("<div> </div>").toggle( fns[0], fns[1], fns[2] );
1220 equals( turn, 1, "Trying toggle with 3 functions, attempt 1 yields 1");
1222 equals( turn, 2, "Trying toggle with 3 functions, attempt 2 yields 2");
1224 equals( turn, 3, "Trying toggle with 3 functions, attempt 3 yields 3");
1226 equals( turn, 1, "Trying toggle with 3 functions, attempt 4 yields 1");
1228 equals( turn, 2, "Trying toggle with 3 functions, attempt 5 yields 2");
1230 $div.unbind("click",fns[0]);
1231 var data = jQuery._data( $div[0], "events" );
1232 ok( !data, "Unbinding one function from toggle unbinds them all");
1234 // manually clean up detached elements
1237 // Test Multi-Toggles
1239 $div = jQuery("<div/>");
1240 $div.toggle(function(){ a.push(1); }, function(){ a.push(2); });
1242 same( a, [1], "Check that a click worked." );
1244 $div.toggle(function(){ b.push(1); }, function(){ b.push(2); });
1246 same( a, [1,2], "Check that a click worked with a second toggle." );
1247 same( b, [1], "Check that a click worked with a second toggle." );
1250 same( a, [1,2,1], "Check that a click worked with a second toggle, second click." );
1251 same( b, [1,2], "Check that a click worked with a second toggle, second click." );
1253 // manually clean up detached elements
1257 test(".live()/.die()", function() {
1260 var submit = 0, div = 0, livea = 0, liveb = 0;
1262 jQuery("div").live("submit", function(){ submit++; return false; });
1263 jQuery("div").live("click", function(){ div++; });
1264 jQuery("div#nothiddendiv").live("click", function(){ livea++; });
1265 jQuery("div#nothiddendivchild").live("click", function(){ liveb++; });
1267 // Nothing should trigger on the body
1268 jQuery("body").trigger("click");
1269 equals( submit, 0, "Click on body" );
1270 equals( div, 0, "Click on body" );
1271 equals( livea, 0, "Click on body" );
1272 equals( liveb, 0, "Click on body" );
1274 // This should trigger two events
1275 submit = 0, div = 0, livea = 0, liveb = 0;
1276 jQuery("div#nothiddendiv").trigger("click");
1277 equals( submit, 0, "Click on div" );
1278 equals( div, 1, "Click on div" );
1279 equals( livea, 1, "Click on div" );
1280 equals( liveb, 0, "Click on div" );
1282 // This should trigger three events (w/ bubbling)
1283 submit = 0, div = 0, livea = 0, liveb = 0;
1284 jQuery("div#nothiddendivchild").trigger("click");
1285 equals( submit, 0, "Click on inner div" );
1286 equals( div, 2, "Click on inner div" );
1287 equals( livea, 1, "Click on inner div" );
1288 equals( liveb, 1, "Click on inner div" );
1290 // This should trigger one submit
1291 submit = 0, div = 0, livea = 0, liveb = 0;
1292 jQuery("div#nothiddendivchild").trigger("submit");
1293 equals( submit, 1, "Submit on div" );
1294 equals( div, 0, "Submit on div" );
1295 equals( livea, 0, "Submit on div" );
1296 equals( liveb, 0, "Submit on div" );
1298 // Make sure no other events were removed in the process
1299 submit = 0, div = 0, livea = 0, liveb = 0;
1300 jQuery("div#nothiddendivchild").trigger("click");
1301 equals( submit, 0, "die Click on inner div" );
1302 equals( div, 2, "die Click on inner div" );
1303 equals( livea, 1, "die Click on inner div" );
1304 equals( liveb, 1, "die Click on inner div" );
1306 // Now make sure that the removal works
1307 submit = 0, div = 0, livea = 0, liveb = 0;
1308 jQuery("div#nothiddendivchild").die("click");
1309 jQuery("div#nothiddendivchild").trigger("click");
1310 equals( submit, 0, "die Click on inner div" );
1311 equals( div, 2, "die Click on inner div" );
1312 equals( livea, 1, "die Click on inner div" );
1313 equals( liveb, 0, "die Click on inner div" );
1315 // Make sure that the click wasn't removed too early
1316 submit = 0, div = 0, livea = 0, liveb = 0;
1317 jQuery("div#nothiddendiv").trigger("click");
1318 equals( submit, 0, "die Click on inner div" );
1319 equals( div, 1, "die Click on inner div" );
1320 equals( livea, 1, "die Click on inner div" );
1321 equals( liveb, 0, "die Click on inner div" );
1323 // Make sure that stopPropgation doesn't stop live events
1324 submit = 0, div = 0, livea = 0, liveb = 0;
1325 jQuery("div#nothiddendivchild").live("click", function(e){ liveb++; e.stopPropagation(); });
1326 jQuery("div#nothiddendivchild").trigger("click");
1327 equals( submit, 0, "stopPropagation Click on inner div" );
1328 equals( div, 1, "stopPropagation Click on inner div" );
1329 equals( livea, 0, "stopPropagation Click on inner div" );
1330 equals( liveb, 1, "stopPropagation Click on inner div" );
1332 // Make sure click events only fire with primary click
1333 submit = 0, div = 0, livea = 0, liveb = 0;
1334 var event = jQuery.Event("click");
1336 jQuery("div#nothiddendiv").trigger(event);
1338 equals( livea, 0, "live secondary click" );
1340 jQuery("div#nothiddendivchild").die("click");
1341 jQuery("div#nothiddendiv").die("click");
1342 jQuery("div").die("click");
1343 jQuery("div").die("submit");
1345 // Test binding with a different context
1346 var clicked = 0, container = jQuery("#qunit-fixture")[0];
1347 jQuery("#foo", container).live("click", function(e){ clicked++; });
1348 jQuery("div").trigger("click");
1349 jQuery("#foo").trigger("click");
1350 jQuery("#qunit-fixture").trigger("click");
1351 jQuery("body").trigger("click");
1352 equals( clicked, 2, "live with a context" );
1354 // Test unbinding with a different context
1355 jQuery("#foo", container).die("click");
1356 jQuery("#foo").trigger("click");
1357 equals( clicked, 2, "die with a context");
1359 // Test binding with event data
1360 jQuery("#foo").live("click", true, function(e){ equals( e.data, true, "live with event data" ); });
1361 jQuery("#foo").trigger("click").die("click");
1363 // Test binding with trigger data
1364 jQuery("#foo").live("click", function(e, data){ equals( data, true, "live with trigger data" ); });
1365 jQuery("#foo").trigger("click", true).die("click");
1367 // Test binding with different this object
1368 jQuery("#foo").live("click", jQuery.proxy(function(e){ equals( this.foo, "bar", "live with event scope" ); }, { foo: "bar" }));
1369 jQuery("#foo").trigger("click").die("click");
1371 // Test binding with different this object, event data, and trigger data
1372 jQuery("#foo").live("click", true, jQuery.proxy(function(e, data){
1373 equals( e.data, true, "live with with different this object, event data, and trigger data" );
1374 equals( this.foo, "bar", "live with with different this object, event data, and trigger data" );
1375 equals( data, true, "live with with different this object, event data, and trigger data")
1376 }, { foo: "bar" }));
1377 jQuery("#foo").trigger("click", true).die("click");
1379 // Verify that return false prevents default action
1380 jQuery("#anchor2").live("click", function(){ return false; });
1381 var hash = window.location.hash;
1382 jQuery("#anchor2").trigger("click");
1383 equals( window.location.hash, hash, "return false worked" );
1384 jQuery("#anchor2").die("click");
1386 // Verify that .preventDefault() prevents default action
1387 jQuery("#anchor2").live("click", function(e){ e.preventDefault(); });
1388 var hash = window.location.hash;
1389 jQuery("#anchor2").trigger("click");
1390 equals( window.location.hash, hash, "e.preventDefault() worked" );
1391 jQuery("#anchor2").die("click");
1393 // Test binding the same handler to multiple points
1395 function callback(){ called++; return false; }
1397 jQuery("#nothiddendiv").live("click", callback);
1398 jQuery("#anchor2").live("click", callback);
1400 jQuery("#nothiddendiv").trigger("click");
1401 equals( called, 1, "Verify that only one click occurred." );
1404 jQuery("#anchor2").trigger("click");
1405 equals( called, 1, "Verify that only one click occurred." );
1407 // Make sure that only one callback is removed
1408 jQuery("#anchor2").die("click", callback);
1411 jQuery("#nothiddendiv").trigger("click");
1412 equals( called, 1, "Verify that only one click occurred." );
1415 jQuery("#anchor2").trigger("click");
1416 equals( called, 0, "Verify that no click occurred." );
1418 // Make sure that it still works if the selector is the same,
1419 // but the event type is different
1420 jQuery("#nothiddendiv").live("foo", callback);
1423 jQuery("#nothiddendiv").die("click", callback);
1426 jQuery("#nothiddendiv").trigger("click");
1427 equals( called, 0, "Verify that no click occurred." );
1430 jQuery("#nothiddendiv").trigger("foo");
1431 equals( called, 1, "Verify that one foo occurred." );
1434 jQuery("#nothiddendiv").die("foo", callback);
1436 // Make sure we don't loose the target by DOM modifications
1437 // after the bubble already reached the liveHandler
1438 var livec = 0, elemDiv = jQuery("#nothiddendivchild").html("<span></span>").get(0);
1440 jQuery("#nothiddendivchild").live("click", function(e){ jQuery("#nothiddendivchild").html(""); });
1441 jQuery("#nothiddendivchild").live("click", function(e){ if(e.target) {livec++;} });
1443 jQuery("#nothiddendiv span").click();
1444 equals( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." );
1445 equals( livec, 1, "Verify that second handler occurred even with nuked target." );
1448 jQuery("#nothiddendivchild").die("click");
1450 // Verify that .live() ocurs and cancel buble in the same order as
1451 // we would expect .bind() and .click() without delegation
1452 var lived = 0, livee = 0;
1454 // bind one pair in one order
1455 jQuery("span#liveSpan1 a").live("click", function(){ lived++; return false; });
1456 jQuery("span#liveSpan1").live("click", function(){ livee++; });
1458 jQuery("span#liveSpan1 a").click();
1459 equals( lived, 1, "Verify that only one first handler occurred." );
1460 equals( livee, 0, "Verify that second handler doesn't." );
1462 // and one pair in inverse
1463 jQuery("span#liveSpan2").live("click", function(){ livee++; });
1464 jQuery("span#liveSpan2 a").live("click", function(){ lived++; return false; });
1468 jQuery("span#liveSpan2 a").click();
1469 equals( lived, 1, "Verify that only one first handler occurred." );
1470 equals( livee, 0, "Verify that second handler doesn't." );
1473 jQuery("span#liveSpan1 a").die("click")
1474 jQuery("span#liveSpan1").die("click");
1475 jQuery("span#liveSpan2 a").die("click");
1476 jQuery("span#liveSpan2").die("click");
1478 // Test this, target and currentTarget are correct
1479 jQuery("span#liveSpan1").live("click", function(e){
1480 equals( this.id, "liveSpan1", "Check the this within a live handler" );
1481 equals( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a live handler" );
1482 equals( e.delegateTarget, document, "Check the event.delegateTarget within a live handler" );
1483 equals( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a live handler" );
1486 jQuery("span#liveSpan1 a").click();
1488 jQuery("span#liveSpan1").die("click");
1490 // Work with deep selectors
1493 function clickB(){ livee++; }
1495 jQuery("#nothiddendiv div").live("click", function(){ livee++; });
1496 jQuery("#nothiddendiv div").live("click", clickB);
1497 jQuery("#nothiddendiv div").live("mouseover", function(){ livee++; });
1499 equals( livee, 0, "No clicks, deep selector." );
1502 jQuery("#nothiddendivchild").trigger("click");
1503 equals( livee, 2, "Click, deep selector." );
1506 jQuery("#nothiddendivchild").trigger("mouseover");
1507 equals( livee, 1, "Mouseover, deep selector." );
1509 jQuery("#nothiddendiv div").die("mouseover");
1512 jQuery("#nothiddendivchild").trigger("click");
1513 equals( livee, 2, "Click, deep selector." );
1516 jQuery("#nothiddendivchild").trigger("mouseover");
1517 equals( livee, 0, "Mouseover, deep selector." );
1519 jQuery("#nothiddendiv div").die("click", clickB);
1522 jQuery("#nothiddendivchild").trigger("click");
1523 equals( livee, 1, "Click, deep selector." );
1525 jQuery("#nothiddendiv div").die("click");
1527 // div must have a tabindex to be focusable
1528 jQuery("#nothiddendiv div")
1529 .attr("tabindex", "0")
1530 .live("blur", function(){
1531 ok( true, "Live div trigger blur." );
1538 test("die all bound events", function(){
1542 var div = jQuery("div#nothiddendivchild");
1544 div.live("click submit", function(){ count++; });
1547 div.trigger("click");
1548 div.trigger("submit");
1550 equals( count, 0, "Make sure no events were triggered." );
1553 test("live with multiple events", function(){
1557 var div = jQuery("div#nothiddendivchild");
1559 div.live("click submit", function(){ count++; });
1561 div.trigger("click");
1562 div.trigger("submit");
1564 equals( count, 2, "Make sure both the click and submit were triggered." );
1566 // manually clean up events from elements outside the fixture
1570 test("live with namespaces", function(){
1573 var count1 = 0, count2 = 0;
1575 jQuery("#liveSpan1").live("foo.bar", function(e){
1576 equals( e.namespace, "bar", "namespace is bar" );
1580 jQuery("#liveSpan1").live("foo.zed", function(e){
1581 equals( e.namespace, "zed", "namespace is zed" );
1585 jQuery("#liveSpan1").trigger("foo.bar");
1586 equals( count1, 1, "Got live foo.bar" );
1587 equals( count2, 0, "Got live foo.bar" );
1589 count1 = 0, count2 = 0;
1591 jQuery("#liveSpan1").trigger("foo.zed");
1592 equals( count1, 0, "Got live foo.zed" );
1593 equals( count2, 1, "Got live foo.zed" );
1596 count1 = 0, count2 = 0;
1598 jQuery("#liveSpan1").die("foo.zed");
1599 jQuery("#liveSpan1").trigger("foo.bar");
1601 equals( count1, 1, "Got live foo.bar after dieing foo.zed" );
1602 equals( count2, 0, "Got live foo.bar after dieing foo.zed" );
1604 count1 = 0, count2 = 0;
1606 jQuery("#liveSpan1").trigger("foo.zed");
1607 equals( count1, 0, "Got live foo.zed" );
1608 equals( count2, 0, "Got live foo.zed" );
1611 jQuery("#liveSpan1").die("foo.bar");
1613 count1 = 0, count2 = 0;
1615 jQuery("#liveSpan1").trigger("foo.bar");
1616 equals( count1, 0, "Did not respond to foo.bar after dieing it" );
1617 equals( count2, 0, "Did not respond to foo.bar after dieing it" );
1619 jQuery("#liveSpan1").trigger("foo.zed");
1620 equals( count1, 0, "Did not trigger foo.zed again" );
1621 equals( count2, 0, "Did not trigger foo.zed again" );
1624 test("live with change", function(){
1627 var selectChange = 0, checkboxChange = 0;
1629 var select = jQuery("select[name='S1']")
1630 select.live("change", function() {
1634 var checkbox = jQuery("#check2"),
1635 checkboxFunction = function(){
1638 checkbox.live("change", checkboxFunction);
1640 // test click on select
1642 // second click that changed it
1644 select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1645 select.trigger("change");
1646 equals( selectChange, 1, "Change on click." );
1648 // test keys on select
1650 select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1651 select.trigger("change");
1652 equals( selectChange, 1, "Change on keyup." );
1654 // test click on checkbox
1655 checkbox.trigger("change");
1656 equals( checkboxChange, 1, "Change on checkbox." );
1658 // test blur/focus on text
1659 var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
1660 text.live("change", function() {
1664 text.val(oldTextVal+"foo");
1665 text.trigger("change");
1666 equals( textChange, 1, "Change on text input." );
1668 text.val(oldTextVal);
1671 // test blur/focus on password
1672 var password = jQuery("#name"), passwordChange = 0, oldPasswordVal = password.val();
1673 password.live("change", function() {
1677 password.val(oldPasswordVal + "foo");
1678 password.trigger("change");
1679 equals( passwordChange, 1, "Change on password input." );
1681 password.val(oldPasswordVal);
1682 password.die("change");
1684 // make sure die works
1688 select.die("change");
1689 select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1690 select.trigger("change");
1691 equals( selectChange, 0, "Die on click works." );
1694 select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1695 select.trigger("change");
1696 equals( selectChange, 0, "Die on keyup works." );
1698 // die specific checkbox
1699 checkbox.die("change", checkboxFunction);
1700 checkbox.trigger("change");
1701 equals( checkboxChange, 1, "Die on checkbox." );
1704 test("live with submit", function() {
1707 var count1 = 0, count2 = 0;
1709 jQuery("#testForm").live("submit", function(ev) {
1711 ev.preventDefault();
1714 jQuery("body").live("submit", function(ev) {
1716 ev.preventDefault();
1719 jQuery("#testForm input[name=sub1]").submit();
1720 equals( count1, 1, "Verify form submit." );
1721 equals( count2, 1, "Verify body submit." );
1723 jQuery("#testForm input[name=sub1]").live("click", function(ev) {
1724 ok( true, "cancelling submit still calls click handler" );
1727 jQuery("#testForm input[name=sub1]")[0].click();
1728 equals( count1, 2, "Verify form submit." );
1729 equals( count2, 2, "Verify body submit." );
1731 jQuery("#testForm button[name=sub4]")[0].click();
1732 equals( count1, 3, "Verify form submit." );
1733 equals( count2, 3, "Verify body submit." );
1735 jQuery("#testForm").die("submit");
1736 jQuery("#testForm input[name=sub1]").die("click");
1737 jQuery("body").die("submit");
1740 test("live with special events", function() {
1743 jQuery.event.special.foo = {
1744 setup: function( data, namespaces, handler ) {
1745 ok( true, "Setup run." );
1747 teardown: function( namespaces ) {
1748 ok( true, "Teardown run." );
1750 add: function( handleObj ) {
1751 ok( true, "Add run." );
1753 remove: function( handleObj ) {
1754 ok( true, "Remove run." );
1756 _default: function( event, arg ) {
1757 ok( event.type === "foo" && arg == 42, "Default run with correct args." );
1762 jQuery("#liveSpan1").live("foo.a", function(e){
1763 ok( true, "Handler 1 run." );
1767 jQuery("#liveSpan1").live("foo.b", function(e){
1768 ok( true, "Handler 2 run." );
1771 // Run: Handler 1, Handler 2, Default
1772 jQuery("#liveSpan1").trigger("foo", 42);
1774 // Run: Handler 1, Default
1775 jQuery("#liveSpan1").trigger("foo.a", 42);
1778 jQuery("#liveSpan1").die("foo.a");
1780 // Run: Handler 2, Default
1781 jQuery("#liveSpan1").trigger("foo", 42);
1783 // Run: remove, teardown
1784 jQuery("#liveSpan1").die("foo");
1786 delete jQuery.event.special.foo;
1789 test(".delegate()/.undelegate()", function() {
1792 var submit = 0, div = 0, livea = 0, liveb = 0;
1794 jQuery("#body").delegate("div", "submit", function(){ submit++; return false; });
1795 jQuery("#body").delegate("div", "click", function(){ div++; });
1796 jQuery("#body").delegate("div#nothiddendiv", "click", function(){ livea++; });
1797 jQuery("#body").delegate("div#nothiddendivchild", "click", function(){ liveb++; });
1799 // Nothing should trigger on the body
1800 jQuery("body").trigger("click");
1801 equals( submit, 0, "Click on body" );
1802 equals( div, 0, "Click on body" );
1803 equals( livea, 0, "Click on body" );
1804 equals( liveb, 0, "Click on body" );
1806 // This should trigger two events
1807 submit = 0, div = 0, livea = 0, liveb = 0;
1808 jQuery("div#nothiddendiv").trigger("click");
1809 equals( submit, 0, "Click on div" );
1810 equals( div, 1, "Click on div" );
1811 equals( livea, 1, "Click on div" );
1812 equals( liveb, 0, "Click on div" );
1814 // This should trigger three events (w/ bubbling)
1815 submit = 0, div = 0, livea = 0, liveb = 0;
1816 jQuery("div#nothiddendivchild").trigger("click");
1817 equals( submit, 0, "Click on inner div" );
1818 equals( div, 2, "Click on inner div" );
1819 equals( livea, 1, "Click on inner div" );
1820 equals( liveb, 1, "Click on inner div" );
1822 // This should trigger one submit
1823 submit = 0, div = 0, livea = 0, liveb = 0;
1824 jQuery("div#nothiddendivchild").trigger("submit");
1825 equals( submit, 1, "Submit on div" );
1826 equals( div, 0, "Submit on div" );
1827 equals( livea, 0, "Submit on div" );
1828 equals( liveb, 0, "Submit on div" );
1830 // Make sure no other events were removed in the process
1831 submit = 0, div = 0, livea = 0, liveb = 0;
1832 jQuery("div#nothiddendivchild").trigger("click");
1833 equals( submit, 0, "undelegate Click on inner div" );
1834 equals( div, 2, "undelegate Click on inner div" );
1835 equals( livea, 1, "undelegate Click on inner div" );
1836 equals( liveb, 1, "undelegate Click on inner div" );
1838 // Now make sure that the removal works
1839 submit = 0, div = 0, livea = 0, liveb = 0;
1840 jQuery("#body").undelegate("div#nothiddendivchild", "click");
1841 jQuery("div#nothiddendivchild").trigger("click");
1842 equals( submit, 0, "undelegate Click on inner div" );
1843 equals( div, 2, "undelegate Click on inner div" );
1844 equals( livea, 1, "undelegate Click on inner div" );
1845 equals( liveb, 0, "undelegate Click on inner div" );
1847 // Make sure that the click wasn't removed too early
1848 submit = 0, div = 0, livea = 0, liveb = 0;
1849 jQuery("div#nothiddendiv").trigger("click");
1850 equals( submit, 0, "undelegate Click on inner div" );
1851 equals( div, 1, "undelegate Click on inner div" );
1852 equals( livea, 1, "undelegate Click on inner div" );
1853 equals( liveb, 0, "undelegate Click on inner div" );
1855 // Make sure that stopPropgation doesn't stop live events
1856 submit = 0, div = 0, livea = 0, liveb = 0;
1857 jQuery("#body").delegate("div#nothiddendivchild", "click", function(e){ liveb++; e.stopPropagation(); });
1858 jQuery("div#nothiddendivchild").trigger("click");
1859 equals( submit, 0, "stopPropagation Click on inner div" );
1860 equals( div, 1, "stopPropagation Click on inner div" );
1861 equals( livea, 0, "stopPropagation Click on inner div" );
1862 equals( liveb, 1, "stopPropagation Click on inner div" );
1864 // Make sure click events only fire with primary click
1865 submit = 0, div = 0, livea = 0, liveb = 0;
1866 var event = jQuery.Event("click");
1868 jQuery("div#nothiddendiv").trigger(event);
1870 equals( livea, 0, "delegate secondary click" );
1872 jQuery("#body").undelegate("div#nothiddendivchild", "click");
1873 jQuery("#body").undelegate("div#nothiddendiv", "click");
1874 jQuery("#body").undelegate("div", "click");
1875 jQuery("#body").undelegate("div", "submit");
1877 // Test binding with a different context
1878 var clicked = 0, container = jQuery("#qunit-fixture")[0];
1879 jQuery("#qunit-fixture").delegate("#foo", "click", function(e){ clicked++; });
1880 jQuery("div").trigger("click");
1881 jQuery("#foo").trigger("click");
1882 jQuery("#qunit-fixture").trigger("click");
1883 jQuery("body").trigger("click");
1884 equals( clicked, 2, "delegate with a context" );
1886 // Test unbinding with a different context
1887 jQuery("#qunit-fixture").undelegate("#foo", "click");
1888 jQuery("#foo").trigger("click");
1889 equals( clicked, 2, "undelegate with a context");
1891 // Test binding with event data
1892 jQuery("#body").delegate("#foo", "click", true, function(e){ equals( e.data, true, "delegate with event data" ); });
1893 jQuery("#foo").trigger("click");
1894 jQuery("#body").undelegate("#foo", "click");
1896 // Test binding with trigger data
1897 jQuery("#body").delegate("#foo", "click", function(e, data){ equals( data, true, "delegate with trigger data" ); });
1898 jQuery("#foo").trigger("click", true);
1899 jQuery("#body").undelegate("#foo", "click");
1901 // Test binding with different this object
1902 jQuery("#body").delegate("#foo", "click", jQuery.proxy(function(e){ equals( this.foo, "bar", "delegate with event scope" ); }, { foo: "bar" }));
1903 jQuery("#foo").trigger("click");
1904 jQuery("#body").undelegate("#foo", "click");
1906 // Test binding with different this object, event data, and trigger data
1907 jQuery("#body").delegate("#foo", "click", true, jQuery.proxy(function(e, data){
1908 equals( e.data, true, "delegate with with different this object, event data, and trigger data" );
1909 equals( this.foo, "bar", "delegate with with different this object, event data, and trigger data" );
1910 equals( data, true, "delegate with with different this object, event data, and trigger data")
1911 }, { foo: "bar" }));
1912 jQuery("#foo").trigger("click", true);
1913 jQuery("#body").undelegate("#foo", "click");
1915 // Verify that return false prevents default action
1916 jQuery("#body").delegate("#anchor2", "click", function(){ return false; });
1917 var hash = window.location.hash;
1918 jQuery("#anchor2").trigger("click");
1919 equals( window.location.hash, hash, "return false worked" );
1920 jQuery("#body").undelegate("#anchor2", "click");
1922 // Verify that .preventDefault() prevents default action
1923 jQuery("#body").delegate("#anchor2", "click", function(e){ e.preventDefault(); });
1924 var hash = window.location.hash;
1925 jQuery("#anchor2").trigger("click");
1926 equals( window.location.hash, hash, "e.preventDefault() worked" );
1927 jQuery("#body").undelegate("#anchor2", "click");
1929 // Test binding the same handler to multiple points
1931 function callback(){ called++; return false; }
1933 jQuery("#body").delegate("#nothiddendiv", "click", callback);
1934 jQuery("#body").delegate("#anchor2", "click", callback);
1936 jQuery("#nothiddendiv").trigger("click");
1937 equals( called, 1, "Verify that only one click occurred." );
1940 jQuery("#anchor2").trigger("click");
1941 equals( called, 1, "Verify that only one click occurred." );
1943 // Make sure that only one callback is removed
1944 jQuery("#body").undelegate("#anchor2", "click", callback);
1947 jQuery("#nothiddendiv").trigger("click");
1948 equals( called, 1, "Verify that only one click occurred." );
1951 jQuery("#anchor2").trigger("click");
1952 equals( called, 0, "Verify that no click occurred." );
1954 // Make sure that it still works if the selector is the same,
1955 // but the event type is different
1956 jQuery("#body").delegate("#nothiddendiv", "foo", callback);
1959 jQuery("#body").undelegate("#nothiddendiv", "click", callback);
1962 jQuery("#nothiddendiv").trigger("click");
1963 equals( called, 0, "Verify that no click occurred." );
1966 jQuery("#nothiddendiv").trigger("foo");
1967 equals( called, 1, "Verify that one foo occurred." );
1970 jQuery("#body").undelegate("#nothiddendiv", "foo", callback);
1972 // Make sure we don't loose the target by DOM modifications
1973 // after the bubble already reached the liveHandler
1974 var livec = 0, elemDiv = jQuery("#nothiddendivchild").html("<span></span>").get(0);
1976 jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ jQuery("#nothiddendivchild").html(""); });
1977 jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ if(e.target) {livec++;} });
1979 jQuery("#nothiddendiv span").click();
1980 equals( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." );
1981 equals( livec, 1, "Verify that second handler occurred even with nuked target." );
1984 jQuery("#body").undelegate("#nothiddendivchild", "click");
1986 // Verify that .live() ocurs and cancel buble in the same order as
1987 // we would expect .bind() and .click() without delegation
1988 var lived = 0, livee = 0;
1990 // bind one pair in one order
1991 jQuery("#body").delegate("span#liveSpan1 a", "click", function(){ lived++; return false; });
1992 jQuery("#body").delegate("span#liveSpan1", "click", function(){ livee++; });
1994 jQuery("span#liveSpan1 a").click();
1995 equals( lived, 1, "Verify that only one first handler occurred." );
1996 equals( livee, 0, "Verify that second handler doesn't." );
1998 // and one pair in inverse
1999 jQuery("#body").delegate("span#liveSpan2", "click", function(){ livee++; });
2000 jQuery("#body").delegate("span#liveSpan2 a", "click", function(){ lived++; return false; });
2004 jQuery("span#liveSpan2 a").click();
2005 equals( lived, 1, "Verify that only one first handler occurred." );
2006 equals( livee, 0, "Verify that second handler doesn't." );
2009 jQuery("#body").undelegate("click");
2011 // Test this, target and currentTarget are correct
2012 jQuery("#body").delegate("span#liveSpan1", "click", function(e){
2013 equals( this.id, "liveSpan1", "Check the this within a delegate handler" );
2014 equals( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a delegate handler" );
2015 equals( e.delegateTarget, document.body, "Check the event.delegateTarget within a delegate handler" );
2016 equals( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a delegate handler" );
2019 jQuery("span#liveSpan1 a").click();
2021 jQuery("#body").undelegate("span#liveSpan1", "click");
2023 // Work with deep selectors
2026 function clickB(){ livee++; }
2028 jQuery("#body").delegate("#nothiddendiv div", "click", function(){ livee++; });
2029 jQuery("#body").delegate("#nothiddendiv div", "click", clickB);
2030 jQuery("#body").delegate("#nothiddendiv div", "mouseover", function(){ livee++; });
2032 equals( livee, 0, "No clicks, deep selector." );
2035 jQuery("#nothiddendivchild").trigger("click");
2036 equals( livee, 2, "Click, deep selector." );
2039 jQuery("#nothiddendivchild").trigger("mouseover");
2040 equals( livee, 1, "Mouseover, deep selector." );
2042 jQuery("#body").undelegate("#nothiddendiv div", "mouseover");
2045 jQuery("#nothiddendivchild").trigger("click");
2046 equals( livee, 2, "Click, deep selector." );
2049 jQuery("#nothiddendivchild").trigger("mouseover");
2050 equals( livee, 0, "Mouseover, deep selector." );
2052 jQuery("#body").undelegate("#nothiddendiv div", "click", clickB);
2055 jQuery("#nothiddendivchild").trigger("click");
2056 equals( livee, 1, "Click, deep selector." );
2058 jQuery("#body").undelegate("#nothiddendiv div", "click");
2061 test("jQuery.off using dispatched jQuery.Event", function() {
2064 var markup = jQuery( '<p><a href="#">target</a></p>' ),
2067 .on( "click.name", "a", function( event ) {
2068 equals( ++count, 1, "event called once before removal" );
2069 jQuery().off( event );
2071 .find( "a" ).click().click().end()
2075 test("stopPropagation() stops directly-bound events on delegated target", function() {
2078 var markup = jQuery( '<div><p><a href="#">target</a></p></div>' );
2080 .on( "click", function() {
2081 ok( false, "directly-bound event on delegate target was called" );
2083 .on( "click", "a", function( e ) {
2084 e.stopPropagation();
2085 ok( true, "delegated handler was called" );
2087 .find("a").click().end()
2091 test("undelegate all bound events", function(){
2095 var div = jQuery("#body");
2097 div.delegate("div#nothiddendivchild", "click submit", function(){ count++; });
2100 jQuery("div#nothiddendivchild").trigger("click");
2101 jQuery("div#nothiddendivchild").trigger("submit");
2103 equals( count, 0, "Make sure no events were triggered." );
2106 test("delegate with multiple events", function(){
2110 var div = jQuery("#body");
2112 div.delegate("div#nothiddendivchild", "click submit", function(){ count++; });
2114 jQuery("div#nothiddendivchild").trigger("click");
2115 jQuery("div#nothiddendivchild").trigger("submit");
2117 equals( count, 2, "Make sure both the click and submit were triggered." );
2119 jQuery("#body").undelegate();
2122 test("delegate with change", function(){
2125 var selectChange = 0, checkboxChange = 0;
2127 var select = jQuery("select[name='S1']");
2128 jQuery("#body").delegate("select[name='S1']", "change", function() {
2132 var checkbox = jQuery("#check2"),
2133 checkboxFunction = function(){
2136 jQuery("#body").delegate("#check2", "change", checkboxFunction);
2138 // test click on select
2140 // second click that changed it
2142 select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
2143 select.trigger("change");
2144 equals( selectChange, 1, "Change on click." );
2146 // test keys on select
2148 select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
2149 select.trigger("change");
2150 equals( selectChange, 1, "Change on keyup." );
2152 // test click on checkbox
2153 checkbox.trigger("change");
2154 equals( checkboxChange, 1, "Change on checkbox." );
2156 // test blur/focus on text
2157 var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
2158 jQuery("#body").delegate("#name", "change", function() {
2162 text.val(oldTextVal+"foo");
2163 text.trigger("change");
2164 equals( textChange, 1, "Change on text input." );
2166 text.val(oldTextVal);
2167 jQuery("#body").die("change");
2169 // test blur/focus on password
2170 var password = jQuery("#name"), passwordChange = 0, oldPasswordVal = password.val();
2171 jQuery("#body").delegate("#name", "change", function() {
2175 password.val(oldPasswordVal + "foo");
2176 password.trigger("change");
2177 equals( passwordChange, 1, "Change on password input." );
2179 password.val(oldPasswordVal);
2180 jQuery("#body").undelegate("#name", "change");
2182 // make sure die works
2186 jQuery("#body").undelegate("select[name='S1']", "change");
2187 select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
2188 select.trigger("change");
2189 equals( selectChange, 0, "Die on click works." );
2192 select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
2193 select.trigger("change");
2194 equals( selectChange, 0, "Die on keyup works." );
2196 // die specific checkbox
2197 jQuery("#body").undelegate("#check2", "change", checkboxFunction);
2198 checkbox.trigger("change");
2199 equals( checkboxChange, 1, "Die on checkbox." );
2202 test("delegate with submit", function() {
2203 var count1 = 0, count2 = 0;
2205 jQuery("#body").delegate("#testForm", "submit", function(ev) {
2207 ev.preventDefault();
2210 jQuery(document).delegate("body", "submit", function(ev) {
2212 ev.preventDefault();
2215 jQuery("#testForm input[name=sub1]").submit();
2216 equals( count1, 1, "Verify form submit." );
2217 equals( count2, 1, "Verify body submit." );
2219 jQuery("#body").undelegate();
2220 jQuery(document).undelegate();
2223 test("undelegate() with only namespaces", function() {
2226 var $delegate = jQuery("#liveHandlerOrder"),
2229 $delegate.delegate("a", "click.ns", function(e) {
2233 jQuery("a", $delegate).eq(0).trigger("click.ns");
2235 equals( count, 1, "delegated click.ns");
2237 $delegate.undelegate(".ns");
2239 jQuery("a", $delegate).eq(1).trigger("click.ns");
2241 equals( count, 1, "no more .ns after undelegate");
2244 test("Non DOM element events", function() {
2249 jQuery(o).bind("nonelementobj", function(e) {
2250 ok( true, "Event on non-DOM object triggered" );
2253 jQuery(o).trigger("nonelementobj");
2256 test("window resize", function() {
2259 jQuery(window).unbind();
2261 jQuery(window).bind("resize", function(){
2262 ok( true, "Resize event fired." );
2263 }).resize().unbind("resize");
2265 ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." );
2268 test("focusin bubbles", function() {
2271 var input = jQuery( "<input type='text' />" ).prependTo( "body" ),
2274 jQuery( "body" ).bind( "focusin.focusinBubblesTest", function(){
2275 equals( 1, order++, "focusin on the body second" );
2278 input.bind( "focusin.focusinBubblesTest", function(){
2279 equals( 0, order++, "focusin on the element first" );
2285 // To make the next focus test work, we need to take focus off the input.
2286 // This will fire another focusin event, so set order to reflect that.
2288 jQuery("#text1")[0].focus();
2290 // jQuery trigger, which calls DOM focus
2292 input.trigger( "focus" );
2295 jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
2298 test("custom events with colons (#3533, #8272)", function() {
2301 var tab = jQuery("<table><tr><td>trigger</td></tr></table>").appendTo("body");
2303 tab.trigger("back:forth");
2304 ok( true, "colon events don't throw" );
2306 ok( false, "colon events die" );
2312 test(".on and .off", function() {
2316 jQuery( '<div id="onandoff"><p>on<b>and</b>off</p><div>worked<em>or</em>borked?</div></div>' ).appendTo( 'body' );
2319 jQuery( "#onandoff" )
2320 .on( "whip", function() {
2321 ok( true, "whipped it good" );
2326 // Direct events only
2328 jQuery( "#onandoff b" )
2329 .on( "click", 5, function( e, trig ) {
2330 counter += e.data + (trig || 9); // twice, 5+9+5+17=36
2332 .one( "click", 7, function( e, trig ) {
2333 counter += e.data + (trig || 11); // once, 7+11=18
2336 .trigger( "click", 17 )
2338 equals( counter, 54, "direct event bindings with data" );
2340 // Delegated events only
2342 jQuery( "#onandoff" )
2343 .on( "click", "em", 5, function( e, trig ) {
2344 counter += e.data + (trig || 9); // twice, 5+9+5+17=36
2346 .one( "click", "em", 7, function( e, trig ) {
2347 counter += e.data + (trig || 11); // once, 7+11=18
2351 .trigger( "click", 17 )
2353 .off( "click", "em" );
2354 equals( counter, 54, "delegated event bindings with data" );
2357 // Mixed event bindings and types
2359 mixfn = function(e, trig) {
2360 counter += (e.data || 0) + (trig || 1);
2362 jQuery( "#onandoff" )
2363 .on( "click clack cluck", "em", 2, mixfn )
2364 .on( "cluck", "b", 7, mixfn )
2365 .on( "cluck", mixfn )
2368 equals( counter, 0, "nothing triggered yet" );
2371 .one( "cluck", 3, mixfn )
2372 .trigger( "cluck", 8 ) // 3+8 2+8 + 0+8 = 29
2374 .trigger( "cluck", 9 ) // 2+9 + 0+9 = 20
2377 equals( counter, 49, "after triggering em element" );
2379 .off( "cluck", function(){} ) // shouldn't remove anything
2380 .trigger( "cluck", 2 ) // 0+2 = 2
2382 equals( counter, 51, "after triggering #onandoff cluck" );
2385 .on( "click", 95, mixfn )
2386 .on( "clack", "p", 97, mixfn )
2387 .one( "cluck", 3, mixfn )
2388 .trigger( "quack", 19 ) // 0
2389 .off( "click clack cluck" )
2392 equals( counter, 51, "after triggering b" );
2394 .trigger( "cluck", 3 ) // 0+3 = 3
2395 .off( "clack", "em", mixfn )
2397 .trigger( "clack" ) // 0
2400 equals( counter, 54, "final triggers" );
2402 .off( "click cluck" );
2404 // We should have removed all the event handlers ... kinda hacky way to check this
2405 var data = jQuery.data[ jQuery( "#onandoff" )[0].expando ] || {};
2406 equals( data.events, undefined, "no events left" );
2408 jQuery("#onandoff").remove();
2411 test("delegated events quickIs", function() {
2413 var markup = jQuery(
2416 'dead<b class="devo-like">beat</b>club'+
2419 'worked<em>or</em>borked?<em></em>'+
2424 check = function(el, expect){
2426 markup.find( el ).trigger( "blink" );
2427 equals( str, expect, "On " + el );
2430 var tag = this.nodeName.toLowerCase();
2431 str += (str && " ") + tag + "|" + e.handleObj.selector;
2432 ok( e.handleObj.quick, "Selector "+ e.handleObj.selector + " on " + tag + " is a quickIs case" );
2435 // tag#id.class[name=value]
2438 .on( "blink", "em", func )
2439 .on( "blink", ".D", func )
2440 .on( "blink", ".devo-like", func )
2441 .on( "blink", ".devo", func )
2442 .on( "blink", ".d", func )
2443 .on( "blink", "p.d", func )
2444 .on( "blink", "#famous", func );
2446 check( ".devo-like", "b|.devo-like p|.D" );
2447 check( ".devo", "" );
2448 check( "p", "p|.D" );
2449 check( "b", "b|.devo-like p|.D" );
2450 check( "em", "em|em q|#famous em|em q|#famous" );
2455 test("fixHooks extensions", function() {
2458 // IE requires focusable elements to be visible, so append to body
2459 var $fixture = jQuery( "<input type='text' id='hook-fixture' />" ).appendTo( "body" ),
2460 saved = jQuery.event.fixHooks.click;
2462 // Ensure the property doesn't exist
2463 $fixture.bind( "click", function( event ) {
2464 ok( !("blurrinessLevel" in event), "event.blurrinessLevel does not exist" );
2466 $fixture.unbind( "click" );
2468 jQuery.event.fixHooks.click = {
2469 filter: function( event, originalEvent ) {
2470 event.blurrinessLevel = 42;
2475 // Trigger a native click and ensure the property is set
2476 $fixture.bind( "click", function( event ) {
2477 equals( event.blurrinessLevel, 42, "event.blurrinessLevel was set" );
2480 delete jQuery.event.fixHooks.click;
2481 $fixture.unbind( "click" ).remove();
2482 jQuery.event.fixHooks.click = saved;
2486 // This code must be run before DOM ready!
2487 var notYetReady, noEarlyExecution,
2491 notYetReady = !jQuery.isReady;
2493 test("jQuery.isReady", function() {
2496 equals(notYetReady, true, "jQuery.isReady should not be true before DOM ready");
2497 equals(jQuery.isReady, true, "jQuery.isReady should be true once DOM is ready");
2500 // Create an event handler.
2501 function makeHandler( testId ) {
2502 // When returned function is executed, push testId onto `order` array
2503 // to ensure execution order. Also, store event handler arg to ensure
2504 // the correct arg is being passed into the event handler.
2505 return function( arg ) {
2511 // Bind to the ready event in every possible way.
2512 jQuery(makeHandler("a"));
2513 jQuery(document).ready(makeHandler("b"));
2514 jQuery(document).bind("ready.readytest", makeHandler("c"));
2516 // Do it twice, just to be sure.
2517 jQuery(makeHandler("d"));
2518 jQuery(document).ready(makeHandler("e"));
2519 jQuery(document).bind("ready.readytest", makeHandler("f"));
2521 noEarlyExecution = order.length == 0;
2523 // This assumes that QUnit tests are run on DOM ready!
2524 test("jQuery ready", function() {
2527 ok(noEarlyExecution, "Handlers bound to DOM ready should not execute before DOM ready");
2529 // Ensure execution order.
2530 same(order, ["a", "b", "d", "e", "c", "f"], "Bound DOM ready handlers should execute in bind-order, but those bound with jQuery(document).bind( 'ready', fn ) will always execute last");
2532 // Ensure handler argument is correct.
2533 equals(args.a, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery");
2534 equals(args.b, jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery");
2535 ok(args.c instanceof jQuery.Event, "Argument passed to fn in jQuery(document).bind( 'ready', fn ) should be an event object");
2539 // Now that the ready event has fired, again bind to the ready event
2540 // in every possible way. These event handlers should execute immediately.
2541 jQuery(makeHandler("g"));
2542 equals(order.pop(), "g", "Event handler should execute immediately");
2543 equals(args.g, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery");
2545 jQuery(document).ready(makeHandler("h"));
2546 equals(order.pop(), "h", "Event handler should execute immediately");
2547 equals(args.h, jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery");
2549 jQuery(document).bind("ready.readytest", makeHandler("never"));
2550 equals(order.length, 0, "Event handler should never execute since DOM ready has already passed");
2553 jQuery(document).unbind("ready.readytest");