event.js 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682
  1. module("event", { teardown: moduleTeardown });
  2. test("null or undefined handler", function() {
  3. expect(2);
  4. // Supports Fixes bug #7229
  5. try {
  6. jQuery("#firstp").on( "click", null );
  7. ok(true, "Passing a null handler will not throw an exception");
  8. } catch ( e ) {}
  9. try {
  10. jQuery("#firstp").on( "click", undefined );
  11. ok(true, "Passing an undefined handler will not throw an exception");
  12. } catch ( e ) {}
  13. });
  14. test("on() with non-null,defined data", function() {
  15. expect(2);
  16. var handler = function( event, data ) {
  17. equal( data, 0, "non-null, defined data (zero) is correctly passed" );
  18. };
  19. jQuery("#foo").on("foo.on", handler);
  20. jQuery("div").on("foo.delegate", "#foo", handler);
  21. jQuery("#foo").trigger("foo", 0);
  22. jQuery("#foo").off("foo.on", handler);
  23. jQuery("div").off("foo.delegate", "#foo");
  24. });
  25. test("Handler changes and .trigger() order", function() {
  26. expect(1);
  27. var markup = jQuery(
  28. "<div><div><p><span><b class=\"a\">b</b></span></p></div></div>"
  29. ),
  30. path = "";
  31. markup
  32. .find( "*" ).addBack().on( "click", function() {
  33. path += this.nodeName.toLowerCase() + " ";
  34. })
  35. .filter( "b" ).on( "click", function( e ) {
  36. // Removing span should not stop propagation to original parents
  37. if ( e.target === this ) {
  38. jQuery(this).parent().remove();
  39. }
  40. });
  41. markup.find( "b" ).trigger( "click" );
  42. equal( path, "b p div div ", "Delivered all events" );
  43. markup.remove();
  44. });
  45. test("on(), with data", function() {
  46. expect(4);
  47. var test, handler, handler2;
  48. handler = function(event) {
  49. ok( event.data, "on() with data, check passed data exists" );
  50. equal( event.data["foo"], "bar", "on() with data, Check value of passed data" );
  51. };
  52. jQuery("#firstp").on("click", {"foo": "bar"}, handler).trigger("click").off("click", handler);
  53. ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
  54. test = function(){};
  55. handler2 = function(event) {
  56. equal( event.data, test, "on() with function data, Check value of passed data" );
  57. };
  58. jQuery("#firstp").on("click", test, handler2).trigger("click").off("click", handler2);
  59. });
  60. test("click(), with data", function() {
  61. expect(3);
  62. var handler = function(event) {
  63. ok( event.data, "on() with data, check passed data exists" );
  64. equal( event.data["foo"], "bar", "on() with data, Check value of passed data" );
  65. };
  66. jQuery("#firstp").on( "click", {"foo": "bar"}, handler).trigger("click").off("click", handler);
  67. ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
  68. });
  69. test("on(), with data, trigger with data", function() {
  70. expect(4);
  71. var handler = function(event, data) {
  72. ok( event.data, "check passed data exists" );
  73. equal( event.data.foo, "bar", "Check value of passed data" );
  74. ok( data, "Check trigger data" );
  75. equal( data.bar, "foo", "Check value of trigger data" );
  76. };
  77. jQuery("#firstp").on("click", {foo: "bar"}, handler).trigger("click", [{bar: "foo"}]).off("click", handler);
  78. });
  79. test("on(), multiple events at once", function() {
  80. expect(2);
  81. var handler,
  82. clickCounter = 0,
  83. mouseoverCounter = 0;
  84. handler = function(event) {
  85. if (event.type === "click") {
  86. clickCounter += 1;
  87. }
  88. else if (event.type === "mouseover") {
  89. mouseoverCounter += 1;
  90. }
  91. };
  92. jQuery("#firstp").on("click mouseover", handler).trigger("click").trigger("mouseover");
  93. equal( clickCounter, 1, "on() with multiple events at once" );
  94. equal( mouseoverCounter, 1, "on() with multiple events at once" );
  95. });
  96. test("on(), five events at once", function() {
  97. expect(1);
  98. var count = 0,
  99. handler = function() {
  100. count++;
  101. };
  102. jQuery("#firstp").on("click mouseover foo bar baz", handler)
  103. .trigger("click").trigger("mouseover")
  104. .trigger("foo").trigger("bar")
  105. .trigger("baz");
  106. equal( count, 5, "on() five events at once" );
  107. });
  108. test("on(), multiple events at once and namespaces", function() {
  109. expect(7);
  110. var cur, div,
  111. obj = {};
  112. div = jQuery("<div/>").on("focusin.a", function(e) {
  113. equal( e.type, cur, "Verify right single event was fired." );
  114. });
  115. cur = "focusin";
  116. div.trigger("focusin.a");
  117. // manually clean up detached elements
  118. div.remove();
  119. div = jQuery("<div/>").on("click mouseover", obj, function(e) {
  120. equal( e.type, cur, "Verify right multi event was fired." );
  121. equal( e.data, obj, "Make sure the data came in correctly." );
  122. });
  123. cur = "click";
  124. div.trigger("click");
  125. cur = "mouseover";
  126. div.trigger("mouseover");
  127. // manually clean up detached elements
  128. div.remove();
  129. div = jQuery("<div/>").on("focusin.a focusout.b", function(e) {
  130. equal( e.type, cur, "Verify right multi event was fired." );
  131. });
  132. cur = "focusin";
  133. div.trigger("focusin.a");
  134. cur = "focusout";
  135. div.trigger("focusout.b");
  136. // manually clean up detached elements
  137. div.remove();
  138. });
  139. test("on(), namespace with special add", function() {
  140. expect(27);
  141. var i = 0,
  142. div = jQuery("<div/>").appendTo("#qunit-fixture").on( "test", function() {
  143. ok( true, "Test event fired." );
  144. });
  145. jQuery.event.special["test"] = {
  146. _default: function( e, data ) {
  147. equal( e.type, "test", "Make sure we're dealing with a test event." );
  148. ok( data, "And that trigger data was passed." );
  149. strictEqual( e.target, div[0], "And that the target is correct." );
  150. equal( this, window, "And that the context is correct." );
  151. },
  152. setup: function() {},
  153. teardown: function() {
  154. ok( true, "Teardown called." );
  155. },
  156. add: function( handleObj ) {
  157. var handler = handleObj.handler;
  158. handleObj.handler = function( e ) {
  159. e.xyz = ++i;
  160. handler.apply( this, arguments );
  161. };
  162. },
  163. remove: function() {
  164. ok( true, "Remove called." );
  165. }
  166. };
  167. div.on( "test.a", { x: 1 }, function( e ) {
  168. ok( !!e.xyz, "Make sure that the data is getting passed through." );
  169. equal( e.data["x"], 1, "Make sure data is attached properly." );
  170. });
  171. div.on( "test.b", { x: 2 }, function( e ) {
  172. ok( !!e.xyz, "Make sure that the data is getting passed through." );
  173. equal( e.data["x"], 2, "Make sure data is attached properly." );
  174. });
  175. // Should trigger 5
  176. div.trigger( "test", 33.33 );
  177. // Should trigger 2
  178. div.trigger( "test.a", "George Harrison" );
  179. // Should trigger 2
  180. div.trigger( "test.b", { year: 1982 } );
  181. // Should trigger 4
  182. div.off("test");
  183. div = jQuery("<div/>").on( "test", function() {
  184. ok( true, "Test event fired." );
  185. });
  186. // Should trigger 2
  187. div.appendTo("#qunit-fixture").remove();
  188. delete jQuery.event.special["test"];
  189. });
  190. test("on(), no data", function() {
  191. expect(1);
  192. var handler = function(event) {
  193. ok ( !event.data, "Check that no data is added to the event object" );
  194. };
  195. jQuery("#firstp").on("click", handler).trigger("click");
  196. });
  197. test("on/one/off(Object)", function(){
  198. expect(6);
  199. var $elem,
  200. clickCounter = 0,
  201. mouseoverCounter = 0;
  202. function handler(event) {
  203. if (event.type === "click") {
  204. clickCounter++;
  205. } else if (event.type === "mouseover") {
  206. mouseoverCounter++;
  207. }
  208. }
  209. function handlerWithData(event) {
  210. if (event.type === "click") {
  211. clickCounter += event.data;
  212. } else if (event.type === "mouseover") {
  213. mouseoverCounter += event.data;
  214. }
  215. }
  216. function trigger(){
  217. $elem.trigger("click").trigger("mouseover");
  218. }
  219. $elem = jQuery("#firstp")
  220. // Regular bind
  221. .on({
  222. "click":handler,
  223. "mouseover":handler
  224. })
  225. // Bind with data
  226. .one({
  227. "click":handlerWithData,
  228. "mouseover":handlerWithData
  229. }, 2 );
  230. trigger();
  231. equal( clickCounter, 3, "on(Object)" );
  232. equal( mouseoverCounter, 3, "on(Object)" );
  233. trigger();
  234. equal( clickCounter, 4, "on(Object)" );
  235. equal( mouseoverCounter, 4, "on(Object)" );
  236. jQuery("#firstp").off({
  237. "click":handler,
  238. "mouseover":handler
  239. });
  240. trigger();
  241. equal( clickCounter, 4, "on(Object)" );
  242. equal( mouseoverCounter, 4, "on(Object)" );
  243. });
  244. test("on/off(Object), on/off(Object, String)", function() {
  245. expect(6);
  246. var events,
  247. clickCounter = 0,
  248. mouseoverCounter = 0,
  249. $p = jQuery("#firstp"),
  250. $a = $p.find("a").eq(0);
  251. events = {
  252. "click": function( event ) {
  253. clickCounter += ( event.data || 1 );
  254. },
  255. "mouseover": function( event ) {
  256. mouseoverCounter += ( event.data || 1 );
  257. }
  258. };
  259. function trigger() {
  260. $a.trigger("click").trigger("mouseover");
  261. }
  262. jQuery( document ).on( events, "#firstp a" );
  263. $p.on( events, "a", 2 );
  264. trigger();
  265. equal( clickCounter, 3, "on" );
  266. equal( mouseoverCounter, 3, "on" );
  267. $p.off( events, "a" );
  268. trigger();
  269. equal( clickCounter, 4, "off" );
  270. equal( mouseoverCounter, 4, "off" );
  271. jQuery( document ).off( events, "#firstp a" );
  272. trigger();
  273. equal( clickCounter, 4, "off" );
  274. equal( mouseoverCounter, 4, "off" );
  275. });
  276. test("on immediate propagation", function() {
  277. expect(2);
  278. var lastClick,
  279. $p = jQuery("#firstp"),
  280. $a = $p.find("a").eq(0);
  281. lastClick = "";
  282. jQuery( document ).on( "click", "#firstp a", function(e) {
  283. lastClick = "click1";
  284. e.stopImmediatePropagation();
  285. });
  286. jQuery( document ).on( "click", "#firstp a", function() {
  287. lastClick = "click2";
  288. });
  289. $a.trigger( "click" );
  290. equal( lastClick, "click1", "on stopImmediatePropagation" );
  291. jQuery( document ).off( "click", "#firstp a" );
  292. lastClick = "";
  293. $p.on( "click", "a", function(e) {
  294. lastClick = "click1";
  295. e.stopImmediatePropagation();
  296. });
  297. $p.on( "click", "a", function() {
  298. lastClick = "click2";
  299. });
  300. $a.trigger( "click" );
  301. equal( lastClick, "click1", "on stopImmediatePropagation" );
  302. $p.off( "click", "**" );
  303. });
  304. test("on bubbling, isDefaultPrevented", function() {
  305. expect(2);
  306. var $anchor2 = jQuery( "#anchor2" ),
  307. $main = jQuery( "#qunit-fixture" ),
  308. fakeClick = function($jq) {
  309. // Use a native click so we don't get jQuery simulated bubbling
  310. if ( document.createEvent ) {
  311. var e = document.createEvent( "MouseEvents" );
  312. e.initEvent( "click", true, true );
  313. $jq[0].dispatchEvent(e);
  314. }
  315. else if ( $jq[0].click ) {
  316. $jq[0].click(); // IE
  317. }
  318. };
  319. $anchor2.on( "click", function(e) {
  320. e.preventDefault();
  321. });
  322. $main.on("click", "#foo", function(e) {
  323. var orig = e.originalEvent;
  324. if ( typeof(orig.defaultPrevented) === "boolean" || typeof(orig.returnValue) === "boolean" || orig["getPreventDefault"] ) {
  325. equal( e.isDefaultPrevented(), true, "isDefaultPrevented true passed to bubbled event" );
  326. } else {
  327. // Opera < 11 doesn't implement any interface we can use, so give it a pass
  328. ok( true, "isDefaultPrevented not supported by this browser, test skipped" );
  329. }
  330. });
  331. fakeClick( $anchor2 );
  332. $anchor2.off( "click" );
  333. $main.off( "click", "**" );
  334. $anchor2.on( "click", function() {
  335. // Let the default action occur
  336. });
  337. $main.on("click", "#foo", function(e) {
  338. equal( e.isDefaultPrevented(), false, "isDefaultPrevented false passed to bubbled event" );
  339. });
  340. fakeClick( $anchor2 );
  341. $anchor2.off( "click" );
  342. $main.off( "click", "**" );
  343. });
  344. test("on(), iframes", function() {
  345. expect( 1 );
  346. // events don't work with iframes, see #939 - this test fails in IE because of contentDocument
  347. var doc = jQuery("#loadediframe").contents();
  348. jQuery("div", doc).on("click", function() {
  349. ok( true, "Binding to element inside iframe" );
  350. }).trigger("click").off("click");
  351. });
  352. test("on(), trigger change on select", function() {
  353. expect(5);
  354. var counter = 0;
  355. function selectOnChange(event) {
  356. equal( event.data, counter++, "Event.data is not a global event object" );
  357. }
  358. jQuery("#form select").each(function(i){
  359. jQuery(this).on("change", i, selectOnChange);
  360. }).trigger("change");
  361. });
  362. test("on(), namespaced events, cloned events", 18, function() {
  363. var firstp = jQuery( "#firstp" );
  364. firstp.on("custom.test",function(){
  365. ok(false, "Custom event triggered");
  366. });
  367. firstp.on("click",function(e){
  368. ok(true, "Normal click triggered");
  369. equal( e.type + e.namespace, "click", "Check that only click events trigger this fn" );
  370. });
  371. firstp.on("click.test",function(e){
  372. var check = "click";
  373. ok( true, "Namespaced click triggered" );
  374. if ( e.namespace ) {
  375. check += "test";
  376. }
  377. equal( e.type + e.namespace, check, "Check that only click/click.test events trigger this fn" );
  378. });
  379. //clone(true) element to verify events are cloned correctly
  380. firstp = firstp.add( firstp.clone( true ).attr( "id", "firstp2" ).insertBefore( firstp ) );
  381. // Trigger both bound fn (8)
  382. firstp.trigger("click");
  383. // Trigger one bound fn (4)
  384. firstp.trigger("click.test");
  385. // Remove only the one fn
  386. firstp.off("click.test");
  387. // Trigger the remaining fn (4)
  388. firstp.trigger("click");
  389. // Remove the remaining namespaced fn
  390. firstp.off(".test");
  391. // Try triggering the custom event (0)
  392. firstp.trigger("custom");
  393. // using contents will get comments regular, text, and comment nodes
  394. jQuery("#nonnodes").contents().on("tester", function () {
  395. equal(this.nodeType, 1, "Check node,textnode,comment on just does real nodes" );
  396. }).trigger("tester");
  397. // Make sure events stick with appendTo'd elements (which are cloned) #2027
  398. jQuery("<a href='#fail' class='test'>test</a>").on( "click", function(){ return false; }).appendTo("#qunit-fixture");
  399. ok( jQuery("a.test").eq(0).triggerHandler("click") === false, "Handler is bound to appendTo'd elements" );
  400. });
  401. test("on(), multi-namespaced events", function() {
  402. expect(6);
  403. var order = [
  404. "click.test.abc",
  405. "click.test.abc",
  406. "click.test",
  407. "click.test.abc",
  408. "click.test",
  409. "custom.test2"
  410. ];
  411. function check(name, msg){
  412. deepEqual( name, order.shift(), msg );
  413. }
  414. jQuery("#firstp").on("custom.test",function() {
  415. check("custom.test", "Custom event triggered");
  416. });
  417. jQuery("#firstp").on("custom.test2",function() {
  418. check("custom.test2", "Custom event triggered");
  419. });
  420. jQuery("#firstp").on("click.test",function() {
  421. check("click.test", "Normal click triggered");
  422. });
  423. jQuery("#firstp").on("click.test.abc",function() {
  424. check("click.test.abc", "Namespaced click triggered");
  425. });
  426. // Those would not trigger/off (#5303)
  427. jQuery("#firstp").trigger("click.a.test");
  428. jQuery("#firstp").off("click.a.test");
  429. // Trigger both bound fn (1)
  430. jQuery("#firstp").trigger("click.test.abc");
  431. // Trigger one bound fn (1)
  432. jQuery("#firstp").trigger("click.abc");
  433. // Trigger two bound fn (2)
  434. jQuery("#firstp").trigger("click.test");
  435. // Remove only the one fn
  436. jQuery("#firstp").off("click.abc");
  437. // Trigger the remaining fn (1)
  438. jQuery("#firstp").trigger("click");
  439. // Remove the remaining fn
  440. jQuery("#firstp").off(".test");
  441. // Trigger the remaining fn (1)
  442. jQuery("#firstp").trigger("custom");
  443. });
  444. test("namespace-only event binding is a no-op", function(){
  445. expect(2);
  446. jQuery("#firstp")
  447. .on( ".whoops", function() {
  448. ok( false, "called a namespace-only event" );
  449. })
  450. .on( "whoops", function() {
  451. ok( true, "called whoops" );
  452. })
  453. .trigger("whoops") // 1
  454. .off(".whoops")
  455. .trigger("whoops") // 2
  456. .off("whoops");
  457. });
  458. test("on(), with same function", function() {
  459. expect(2);
  460. var count = 0, func = function(){
  461. count++;
  462. };
  463. jQuery("#liveHandlerOrder").on("foo.bar", func).on("foo.zar", func);
  464. jQuery("#liveHandlerOrder").trigger("foo.bar");
  465. equal(count, 1, "Verify binding function with multiple namespaces." );
  466. jQuery("#liveHandlerOrder").off("foo.bar", func).off("foo.zar", func);
  467. jQuery("#liveHandlerOrder").trigger("foo.bar");
  468. equal(count, 1, "Verify that removing events still work." );
  469. });
  470. test("on(), make sure order is maintained", function() {
  471. expect(1);
  472. var elem = jQuery("#firstp"), log = [], check = [];
  473. jQuery.each( new Array(100), function( i ) {
  474. elem.on( "click", function(){
  475. log.push( i );
  476. });
  477. check.push( i );
  478. });
  479. elem.trigger("click");
  480. equal( log.join(","), check.join(","), "Make sure order was maintained." );
  481. elem.off("click");
  482. });
  483. test("on(), with different this object", function() {
  484. expect(4);
  485. var thisObject = { myThis: true },
  486. data = { myData: true },
  487. handler1 = function() {
  488. equal( this, thisObject, "on() with different this object" );
  489. },
  490. handler2 = function( event ) {
  491. equal( this, thisObject, "on() with different this object and data" );
  492. equal( event.data, data, "on() with different this object and data" );
  493. };
  494. jQuery("#firstp")
  495. .on("click", jQuery.proxy(handler1, thisObject)).trigger("click").off("click", handler1)
  496. .on("click", data, jQuery.proxy(handler2, thisObject)).trigger("click").off("click", handler2);
  497. ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using different this object and data." );
  498. });
  499. test("on(name, false), off(name, false)", function() {
  500. expect(3);
  501. var main = 0;
  502. jQuery("#qunit-fixture").on("click", function(){ main++; });
  503. jQuery("#ap").trigger("click");
  504. equal( main, 1, "Verify that the trigger happened correctly." );
  505. main = 0;
  506. jQuery("#ap").on("click", false);
  507. jQuery("#ap").trigger("click");
  508. equal( main, 0, "Verify that no bubble happened." );
  509. main = 0;
  510. jQuery("#ap").off("click", false);
  511. jQuery("#ap").trigger("click");
  512. equal( main, 1, "Verify that the trigger happened correctly." );
  513. // manually clean up events from elements outside the fixture
  514. jQuery("#qunit-fixture").off("click");
  515. });
  516. test("on(name, selector, false), off(name, selector, false)", function() {
  517. expect(3);
  518. var main = 0;
  519. jQuery("#qunit-fixture").on("click", "#ap", function(){ main++; });
  520. jQuery("#ap").trigger("click");
  521. equal( main, 1, "Verify that the trigger happened correctly." );
  522. main = 0;
  523. jQuery("#ap").on("click", "#groups", false);
  524. jQuery("#groups").trigger("click");
  525. equal( main, 0, "Verify that no bubble happened." );
  526. main = 0;
  527. jQuery("#ap").off("click", "#groups", false);
  528. jQuery("#groups").trigger("click");
  529. equal( main, 1, "Verify that the trigger happened correctly." );
  530. jQuery("#qunit-fixture").off("click", "#ap");
  531. });
  532. test("on()/trigger()/off() on plain object", function() {
  533. expect( 7 );
  534. var events,
  535. obj = {};
  536. // Make sure it doesn't complain when no events are found
  537. jQuery(obj).trigger("test");
  538. // Make sure it doesn't complain when no events are found
  539. jQuery(obj).off("test");
  540. jQuery(obj).on({
  541. "test": function() {
  542. ok( true, "Custom event run." );
  543. },
  544. "submit": function() {
  545. ok( true, "Custom submit event run." );
  546. }
  547. });
  548. events = jQuery._data(obj, "events");
  549. ok( events, "Object has events bound." );
  550. equal( obj["events"], undefined, "Events object on plain objects is not events" );
  551. equal( obj["test"], undefined, "Make sure that test event is not on the plain object." );
  552. equal( obj["handle"], undefined, "Make sure that the event handler is not on the plain object." );
  553. // Should trigger 1
  554. jQuery(obj).trigger("test");
  555. jQuery(obj).trigger("submit");
  556. jQuery(obj).off("test");
  557. jQuery(obj).off("submit");
  558. // Should trigger 0
  559. jQuery(obj).trigger("test");
  560. // Make sure it doesn't complain when no events are found
  561. jQuery(obj).off("test");
  562. equal( obj && obj[ jQuery.expando ] &&
  563. obj[ jQuery.expando ][ jQuery.expando ] &&
  564. obj[ jQuery.expando ][ jQuery.expando ]["events"], undefined, "Make sure events object is removed" );
  565. });
  566. test("off(type)", function() {
  567. expect( 1 );
  568. var message, func,
  569. $elem = jQuery("#firstp");
  570. function error(){
  571. ok( false, message );
  572. }
  573. message = "unbind passing function";
  574. $elem.on("error1", error).off("error1", error).triggerHandler("error1");
  575. message = "unbind all from event";
  576. $elem.on("error1", error).off("error1").triggerHandler("error1");
  577. message = "unbind all";
  578. $elem.on("error1", error).off().triggerHandler("error1");
  579. message = "unbind many with function";
  580. $elem.on("error1 error2",error)
  581. .off("error1 error2", error )
  582. .trigger("error1").triggerHandler("error2");
  583. message = "unbind many"; // #3538
  584. $elem.on("error1 error2", error)
  585. .off("error1 error2")
  586. .trigger("error1").triggerHandler("error2");
  587. message = "unbind without a type or handler";
  588. $elem.on("error1 error2.test",error)
  589. .off()
  590. .trigger("error1").triggerHandler("error2");
  591. // Should only unbind the specified function
  592. jQuery( document ).on( "click", function(){
  593. ok( true, "called handler after selective removal");
  594. });
  595. func = function() {};
  596. jQuery( document )
  597. .on( "click", func )
  598. .off( "click", func )
  599. .trigger("click")
  600. .off( "click" );
  601. });
  602. test("off(eventObject)", function() {
  603. expect(4);
  604. var $elem = jQuery("#firstp"),
  605. num;
  606. function assert( expected ){
  607. num = 0;
  608. $elem.trigger("foo").triggerHandler("bar");
  609. equal( num, expected, "Check the right handlers are triggered" );
  610. }
  611. $elem
  612. // This handler shouldn't be unbound
  613. .on("foo", function(){
  614. num += 1;
  615. })
  616. .on("foo", function(e){
  617. $elem.off( e );
  618. num += 2;
  619. })
  620. // Neither this one
  621. .on("bar", function(){
  622. num += 4;
  623. });
  624. assert( 7 );
  625. assert( 5 );
  626. $elem.off("bar");
  627. assert( 1 );
  628. $elem.off();
  629. assert( 0 );
  630. });
  631. if ( jQuery.fn.hover ) {
  632. test("hover() mouseenter mouseleave", function() {
  633. expect(1);
  634. var times = 0,
  635. handler1 = function() { ++times; },
  636. handler2 = function() { ++times; };
  637. jQuery("#firstp")
  638. .hover(handler1, handler2)
  639. .mouseenter().mouseleave()
  640. .off("mouseenter", handler1)
  641. .off("mouseleave", handler2)
  642. .hover(handler1)
  643. .mouseenter().mouseleave()
  644. .off("mouseenter mouseleave", handler1)
  645. .mouseenter().mouseleave();
  646. equal( times, 4, "hover handlers fired" );
  647. });
  648. }
  649. test("mouseover triggers mouseenter", function() {
  650. expect(1);
  651. var count = 0,
  652. elem = jQuery("<a />");
  653. elem.on( "mouseenter", function () {
  654. count++;
  655. });
  656. elem.trigger("mouseover");
  657. equal(count, 1, "make sure mouseover triggers a mouseenter" );
  658. elem.remove();
  659. });
  660. test("withinElement implemented with jQuery.contains()", function() {
  661. expect(1);
  662. jQuery("#qunit-fixture").append("<div id='jc-outer'><div id='jc-inner'></div></div>");
  663. jQuery("#jc-outer").on("mouseenter mouseleave", function( event ) {
  664. equal( this.id, "jc-outer", this.id + " " + event.type );
  665. }).trigger("mouseenter");
  666. jQuery("#jc-inner").trigger("mousenter");
  667. jQuery("#jc-outer").off("mouseenter mouseleave").remove();
  668. jQuery("#jc-inner").remove();
  669. });
  670. test("mouseenter, mouseleave don't catch exceptions", function() {
  671. expect(2);
  672. var elem = jQuery("#firstp").on( "mouseenter mouseleave", function() {
  673. throw "an Exception";
  674. });
  675. try {
  676. elem.trigger("mouseenter");
  677. } catch (e) {
  678. equal( e, "an Exception", "mouseenter doesn't catch exceptions" );
  679. }
  680. try {
  681. elem.trigger("mouseleave");
  682. } catch (e) {
  683. equal( e, "an Exception", "mouseleave doesn't catch exceptions" );
  684. }
  685. });
  686. if ( jQuery.fn.click ) {
  687. test("trigger() shortcuts", function() {
  688. expect(6);
  689. var counter, clickCounter,
  690. elem = jQuery("<li><a href='#'>Change location</a></li>").prependTo("#firstUL");
  691. elem.find("a").on("click", function() {
  692. var close = jQuery("spanx", this); // same with jQuery(this).find("span");
  693. equal( close.length, 0, "Context element does not exist, length must be zero" );
  694. ok( !close[0], "Context element does not exist, direct access to element must return undefined" );
  695. return false;
  696. }).click();
  697. // manually clean up detached elements
  698. elem.remove();
  699. jQuery("#check1").click(function() {
  700. ok( true, "click event handler for checkbox gets fired twice, see #815" );
  701. }).click();
  702. counter = 0;
  703. jQuery("#firstp")[0].onclick = function() {
  704. counter++;
  705. };
  706. jQuery("#firstp").click();
  707. equal( counter, 1, "Check that click, triggers onclick event handler also" );
  708. clickCounter = 0;
  709. jQuery("#simon1")[0].onclick = function() {
  710. clickCounter++;
  711. };
  712. jQuery("#simon1").click();
  713. equal( clickCounter, 1, "Check that click, triggers onclick event handler on an a tag also" );
  714. elem = jQuery("<img />").load(function(){
  715. ok( true, "Trigger the load event, using the shortcut .load() (#2819)");
  716. }).load();
  717. // manually clean up detached elements
  718. elem.remove();
  719. // test that special handlers do not blow up with VML elements (#7071)
  720. jQuery("<xml:namespace ns='urn:schemas-microsoft-com:vml' prefix='v' />").appendTo("head");
  721. jQuery("<v:oval id='oval' style='width:100pt;height:75pt;' fillcolor='red'> </v:oval>").appendTo("#form");
  722. jQuery("#oval").click().keydown();
  723. });
  724. }
  725. test("trigger() bubbling", function() {
  726. expect(18);
  727. var win = 0, doc = 0, html = 0, body = 0, main = 0, ap = 0;
  728. jQuery(window).on("click", function(){ win++; });
  729. jQuery(document).on("click", function( e ){ if ( e.target !== document) { doc++; } });
  730. jQuery("html").on("click", function(){ html++; });
  731. jQuery("body").on("click", function(){ body++; });
  732. jQuery("#qunit-fixture").on("click", function(){ main++; });
  733. jQuery("#ap").on("click", function(){ ap++; return false; });
  734. jQuery("html").trigger("click");
  735. equal( win, 1, "HTML bubble" );
  736. equal( doc, 1, "HTML bubble" );
  737. equal( html, 1, "HTML bubble" );
  738. jQuery("body").trigger("click");
  739. equal( win, 2, "Body bubble" );
  740. equal( doc, 2, "Body bubble" );
  741. equal( html, 2, "Body bubble" );
  742. equal( body, 1, "Body bubble" );
  743. jQuery("#qunit-fixture").trigger("click");
  744. equal( win, 3, "Main bubble" );
  745. equal( doc, 3, "Main bubble" );
  746. equal( html, 3, "Main bubble" );
  747. equal( body, 2, "Main bubble" );
  748. equal( main, 1, "Main bubble" );
  749. jQuery("#ap").trigger("click");
  750. equal( doc, 3, "ap bubble" );
  751. equal( html, 3, "ap bubble" );
  752. equal( body, 2, "ap bubble" );
  753. equal( main, 1, "ap bubble" );
  754. equal( ap, 1, "ap bubble" );
  755. jQuery( document ).trigger("click");
  756. equal( win, 4, "doc bubble" );
  757. // manually clean up events from elements outside the fixture
  758. jQuery(document).off("click");
  759. jQuery("html, body, #qunit-fixture").off("click");
  760. });
  761. test("trigger(type, [data], [fn])", function() {
  762. expect(16);
  763. var $elem, pass, form, elem2,
  764. handler = function(event, a, b, c) {
  765. equal( event.type, "click", "check passed data" );
  766. equal( a, 1, "check passed data" );
  767. equal( b, "2", "check passed data" );
  768. equal( c, "abc", "check passed data" );
  769. return "test";
  770. };
  771. $elem = jQuery("#firstp");
  772. // Simulate a "native" click
  773. $elem[0].click = function(){
  774. ok( true, "Native call was triggered" );
  775. };
  776. jQuery( document ).on("mouseenter", "#firstp", function(){
  777. ok( true, "Trigger mouseenter bound by on" );
  778. });
  779. jQuery( document ).on("mouseleave", "#firstp", function(){
  780. ok( true, "Trigger mouseleave bound by on" );
  781. });
  782. $elem.trigger("mouseenter");
  783. $elem.trigger("mouseleave");
  784. jQuery( document ).off( "mouseenter mouseleave", "#firstp");
  785. // Triggers handlers and native
  786. // Trigger 5
  787. $elem.on("click", handler).trigger("click", [1, "2", "abc"]);
  788. // Simulate a "native" click
  789. $elem[0].click = function(){
  790. ok( false, "Native call was triggered" );
  791. };
  792. // Trigger only the handlers (no native)
  793. // Triggers 5
  794. equal( $elem.triggerHandler("click", [1, "2", "abc"]), "test", "Verify handler response" );
  795. pass = true;
  796. try {
  797. elem2 = jQuery("#form input").eq(0);
  798. elem2.get(0).style.display = "none";
  799. elem2.trigger("focus");
  800. } catch( e ) {
  801. pass = false;
  802. }
  803. ok( pass, "Trigger focus on hidden element" );
  804. pass = true;
  805. try {
  806. jQuery("#qunit-fixture table").eq(0).on("test:test", function(){}).trigger("test:test");
  807. } catch ( e ) {
  808. pass = false;
  809. }
  810. ok( pass, "Trigger on a table with a colon in the even type, see #3533" );
  811. form = jQuery("<form action=''></form>").appendTo("body");
  812. // Make sure it can be prevented locally
  813. form.on( "submit", function(){
  814. ok( true, "Local `on` still works." );
  815. return false;
  816. });
  817. // Trigger 1
  818. form.trigger("submit");
  819. form.off("submit");
  820. jQuery(document).on( "submit", function(){
  821. ok( true, "Make sure bubble works up to document." );
  822. return false;
  823. });
  824. // Trigger 1
  825. form.trigger("submit");
  826. jQuery(document).off("submit");
  827. form.remove();
  828. });
  829. test( "submit event bubbles on copied forms (#11649)", function() {
  830. expect( 3 );
  831. var $formByClone, $formByHTML,
  832. $testForm = jQuery("#testForm"),
  833. $fixture = jQuery("#qunit-fixture"),
  834. $wrapperDiv = jQuery("<div/>").appendTo( $fixture );
  835. function noSubmit( e ) {
  836. e.preventDefault();
  837. }
  838. function delegatedSubmit() {
  839. ok( true, "Make sure submit event bubbles up." );
  840. return false;
  841. }
  842. // Attach a delegated submit handler to the parent element
  843. $fixture.on( "submit", "form", delegatedSubmit );
  844. // Trigger form submission to introduce the _submit_attached property
  845. $testForm.on( "submit", noSubmit ).find("input[name=sub1]").trigger("click");
  846. // Copy the form via .clone() and .html()
  847. $formByClone = $testForm.clone( true, true ).removeAttr("id");
  848. $formByHTML = jQuery( jQuery.parseHTML($fixture.html()) ).filter("#testForm").removeAttr("id");
  849. $wrapperDiv.append( $formByClone, $formByHTML );
  850. // Check submit bubbling on the copied forms
  851. $wrapperDiv.find("form").on( "submit", noSubmit ).find("input[name=sub1]").trigger("click");
  852. // Clean up
  853. $wrapperDiv.remove();
  854. $fixture.off( "submit", "form", delegatedSubmit );
  855. $testForm.off( "submit", noSubmit );
  856. });
  857. test( "change event bubbles on copied forms (#11796)", function(){
  858. expect( 3 );
  859. var $formByClone, $formByHTML,
  860. $form = jQuery("#form"),
  861. $fixture = jQuery("#qunit-fixture"),
  862. $wrapperDiv = jQuery("<div/>").appendTo( $fixture );
  863. function delegatedChange() {
  864. ok( true, "Make sure change event bubbles up." );
  865. return false;
  866. }
  867. // Attach a delegated change handler to the form
  868. $fixture.on( "change", "form", delegatedChange );
  869. // Trigger change event to introduce the _change_attached property
  870. $form.find("select[name=select1]").val("1").trigger("change");
  871. // Copy the form via .clone() and .html()
  872. $formByClone = $form.clone( true, true ).removeAttr("id");
  873. $formByHTML = jQuery( jQuery.parseHTML($fixture.html()) ).filter("#form").removeAttr("id");
  874. $wrapperDiv.append( $formByClone, $formByHTML );
  875. // Check change bubbling on the copied forms
  876. $wrapperDiv.find("form select[name=select1]").val("2").trigger("change");
  877. // Clean up
  878. $wrapperDiv.remove();
  879. $fixture.off( "change", "form", delegatedChange );
  880. });
  881. test("trigger(eventObject, [data], [fn])", function() {
  882. expect(28);
  883. var event,
  884. $parent = jQuery("<div id='par' />").appendTo("body"),
  885. $child = jQuery("<p id='child'>foo</p>").appendTo( $parent );
  886. $parent.get( 0 ).style.display = "none";
  887. event = jQuery.Event("noNew");
  888. ok( event !== window, "Instantiate jQuery.Event without the 'new' keyword" );
  889. equal( event.type, "noNew", "Verify its type" );
  890. equal( event.isDefaultPrevented(), false, "Verify isDefaultPrevented" );
  891. equal( event.isPropagationStopped(), false, "Verify isPropagationStopped" );
  892. equal( event.isImmediatePropagationStopped(), false, "Verify isImmediatePropagationStopped" );
  893. event.preventDefault();
  894. equal( event.isDefaultPrevented(), true, "Verify isDefaultPrevented" );
  895. event.stopPropagation();
  896. equal( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
  897. event.isPropagationStopped = function(){ return false; };
  898. event.stopImmediatePropagation();
  899. equal( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
  900. equal( event.isImmediatePropagationStopped(), true, "Verify isPropagationStopped" );
  901. $parent.on("foo",function( e ) {
  902. // Tries bubbling
  903. equal( e.type, "foo", "Verify event type when passed passing an event object" );
  904. equal( e.target.id, "child", "Verify event.target when passed passing an event object" );
  905. equal( e.currentTarget.id, "par", "Verify event.currentTarget when passed passing an event object" );
  906. equal( e.secret, "boo!", "Verify event object's custom attribute when passed passing an event object" );
  907. });
  908. // test with an event object
  909. event = new jQuery.Event("foo");
  910. event.secret = "boo!";
  911. $child.trigger(event);
  912. // test with a literal object
  913. $child.trigger({"type": "foo", "secret": "boo!"});
  914. $parent.off();
  915. function error(){
  916. ok( false, "This assertion shouldn't be reached");
  917. }
  918. $parent.on("foo", error );
  919. $child.on("foo",function(e, a, b, c ){
  920. equal( arguments.length, 4, "Check arguments length");
  921. equal( a, 1, "Check first custom argument");
  922. equal( b, 2, "Check second custom argument");
  923. equal( c, 3, "Check third custom argument");
  924. equal( e.isDefaultPrevented(), false, "Verify isDefaultPrevented" );
  925. equal( e.isPropagationStopped(), false, "Verify isPropagationStopped" );
  926. equal( e.isImmediatePropagationStopped(), false, "Verify isImmediatePropagationStopped" );
  927. // Skips both errors
  928. e.stopImmediatePropagation();
  929. return "result";
  930. });
  931. // We should add this back in when we want to test the order
  932. // in which event handlers are iterated.
  933. //$child.on("foo", error );
  934. event = new jQuery.Event("foo");
  935. $child.trigger( event, [1,2,3] ).off();
  936. equal( event.result, "result", "Check event.result attribute");
  937. // Will error if it bubbles
  938. $child.triggerHandler("foo");
  939. $child.off();
  940. $parent.off().remove();
  941. // Ensure triggerHandler doesn't molest its event object (#xxx)
  942. event = jQuery.Event( "zowie" );
  943. jQuery( document ).triggerHandler( event );
  944. equal( event.type, "zowie", "Verify its type" );
  945. equal( event.isPropagationStopped(), false, "propagation not stopped" );
  946. equal( event.isDefaultPrevented(), false, "default not prevented" );
  947. });
  948. // Explicitly introduce global variable for oldIE so QUnit doesn't complain if checking globals
  949. window.onclick = undefined;
  950. test(".trigger() bubbling on disconnected elements (#10489)", function() {
  951. expect(2);
  952. jQuery( window ).on( "click", function(){
  953. ok( false, "click fired on window" );
  954. });
  955. jQuery( "<div><p>hi</p></div>" )
  956. .on( "click", function() {
  957. ok( true, "click fired on div" );
  958. })
  959. .find( "p" )
  960. .on( "click", function() {
  961. ok( true, "click fired on p" );
  962. })
  963. .trigger("click")
  964. .off( "click" )
  965. .end()
  966. .off( "click" )
  967. .remove();
  968. jQuery( window ).off( "click" );
  969. });
  970. test(".trigger() doesn't bubble load event (#10717)", function() {
  971. expect(1);
  972. jQuery( window ).on( "load", function(){
  973. ok( false, "load fired on window" );
  974. });
  975. // It's not an image, but as long as it fires load...
  976. jQuery("<img src='index.html' />")
  977. .appendTo( "body" )
  978. .on( "load", function() {
  979. ok( true, "load fired on img" );
  980. })
  981. .trigger( "load" )
  982. .remove();
  983. jQuery( window ).off( "load" );
  984. });
  985. test("Delegated events in SVG (#10791; #13180)", function() {
  986. expect(2);
  987. var useElem, e,
  988. svg = jQuery(
  989. "<svg height='1' version='1.1' width='1' xmlns='http://www.w3.org/2000/svg'>" +
  990. "<defs><rect id='ref' x='10' y='20' width='100' height='60' r='10' rx='10' ry='10'></rect></defs>" +
  991. "<rect class='svg-by-class' x='10' y='20' width='100' height='60' r='10' rx='10' ry='10'></rect>" +
  992. "<rect id='svg-by-id' x='10' y='20' width='100' height='60' r='10' rx='10' ry='10'></rect>" +
  993. "<use id='use' xlink:href='#ref'></use>" +
  994. "</svg>"
  995. );
  996. jQuery("#qunit-fixture")
  997. .append( svg )
  998. .on( "click", "#svg-by-id", function() {
  999. ok( true, "delegated id selector" );
  1000. })
  1001. .on( "click", "[class~='svg-by-class']", function() {
  1002. ok( true, "delegated class selector" );
  1003. })
  1004. .find( "#svg-by-id, [class~='svg-by-class']" )
  1005. .trigger("click")
  1006. .end();
  1007. // Fire a native click on an SVGElementInstance (the instance tree of an SVG <use>)
  1008. // to confirm that it doesn't break our event delegation handling (#13180)
  1009. useElem = svg.find("#use")[0];
  1010. if ( document.createEvent && useElem && useElem.instanceRoot ) {
  1011. e = document.createEvent("MouseEvents");
  1012. e.initEvent( "click", true, true );
  1013. useElem.instanceRoot.dispatchEvent( e );
  1014. }
  1015. jQuery("#qunit-fixture").off("click");
  1016. });
  1017. test("Delegated events in forms (#10844; #11145; #8165; #11382, #11764)", function() {
  1018. expect(5);
  1019. // Alias names like "id" cause havoc
  1020. var form = jQuery(
  1021. "<form id='myform'>" +
  1022. "<input type='text' name='id' value='secret agent man' />" +
  1023. "</form>"
  1024. )
  1025. .on( "submit", function( event ) {
  1026. event.preventDefault();
  1027. })
  1028. .appendTo("body");
  1029. jQuery("body")
  1030. .on( "submit", "#myform", function() {
  1031. ok( true, "delegated id selector with aliased id" );
  1032. })
  1033. .find("#myform")
  1034. .trigger("submit")
  1035. .end()
  1036. .off("submit");
  1037. form.append("<input type='text' name='disabled' value='differently abled' />");
  1038. jQuery("body")
  1039. .on( "submit", "#myform", function() {
  1040. ok( true, "delegated id selector with aliased disabled" );
  1041. })
  1042. .find("#myform")
  1043. .trigger("submit")
  1044. .end()
  1045. .off("submit");
  1046. form
  1047. .append( "<button id='nestyDisabledBtn'><span>Zing</span></button>" )
  1048. .on( "click", "#nestyDisabledBtn", function() {
  1049. ok( true, "click on enabled/disabled button with nesty elements" );
  1050. })
  1051. .on( "mouseover", "#nestyDisabledBtn", function() {
  1052. ok( true, "mouse on enabled/disabled button with nesty elements" );
  1053. })
  1054. .find( "span" )
  1055. .trigger( "click" ) // yep
  1056. .trigger( "mouseover" ) // yep
  1057. .end()
  1058. .find( "#nestyDisabledBtn" ).prop( "disabled", true ).end()
  1059. .find( "span" )
  1060. .trigger( "click" ) // nope
  1061. .trigger( "mouseover" ) // yep
  1062. .end()
  1063. .off( "click" );
  1064. form.remove();
  1065. });
  1066. test("Submit event can be stopped (#11049)", function() {
  1067. expect(1);
  1068. // Since we manually bubble in IE, make sure inner handlers get a chance to cancel
  1069. var form = jQuery(
  1070. "<form id='myform'>" +
  1071. "<input type='text' name='sue' value='bawls' />" +
  1072. "<input type='submit' />" +
  1073. "</form>"
  1074. )
  1075. .appendTo("body");
  1076. jQuery( "body" )
  1077. .on( "submit", function() {
  1078. ok( true, "submit bubbled on first handler" );
  1079. return false;
  1080. })
  1081. .find( "#myform input[type=submit]" )
  1082. .each( function(){ this.click(); } )
  1083. .end()
  1084. .on( "submit", function() {
  1085. ok( false, "submit bubbled on second handler" );
  1086. return false;
  1087. })
  1088. .find( "#myform input[type=submit]" )
  1089. .each( function(){
  1090. jQuery( this.form ).on( "submit", function( e ) {
  1091. e.preventDefault();
  1092. e.stopPropagation();
  1093. });
  1094. this.click();
  1095. })
  1096. .end()
  1097. .off( "submit" );
  1098. form.remove();
  1099. });
  1100. // Test beforeunload event only if it supported (i.e. not Opera)
  1101. if ( window.onbeforeunload === null ) {
  1102. asyncTest("on(beforeunload)", 1, function() {
  1103. var iframe = jQuery(jQuery.parseHTML("<iframe src='data/event/onbeforeunload.html'><iframe>"));
  1104. window.onmessage = function( event ) {
  1105. var payload = JSON.parse( event.data );
  1106. ok( payload.event, "beforeunload", "beforeunload event" );
  1107. iframe.remove();
  1108. window.onmessage = null;
  1109. start();
  1110. };
  1111. iframe.appendTo("#qunit-fixture");
  1112. });
  1113. }
  1114. test("jQuery.Event( type, props )", function() {
  1115. expect(5);
  1116. var event = jQuery.Event( "keydown", { keyCode: 64 }),
  1117. handler = function( event ) {
  1118. ok( "keyCode" in event, "Special property 'keyCode' exists" );
  1119. equal( event.keyCode, 64, "event.keyCode has explicit value '64'" );
  1120. };
  1121. // Supports jQuery.Event implementation
  1122. equal( event.type, "keydown", "Verify type" );
  1123. // ensure "type" in props won't clobber the one set by constructor
  1124. equal( jQuery.inArray("type", jQuery.event.props), -1, "'type' property not in props (#10375)" );
  1125. ok( "keyCode" in event, "Special 'keyCode' property exists" );
  1126. jQuery("body").on( "keydown", handler ).trigger( event );
  1127. jQuery("body").off( "keydown" );
  1128. });
  1129. test("jQuery.Event properties", function(){
  1130. expect(12);
  1131. var handler,
  1132. $structure = jQuery("<div id='ancestor'><p id='delegate'><span id='target'>shiny</span></p></div>"),
  1133. $target = $structure.find("#target");
  1134. handler = function( e ) {
  1135. strictEqual( e.currentTarget, this, "currentTarget at " + this.id );
  1136. equal( e.isTrigger, 3, "trigger at " + this.id );
  1137. };
  1138. $structure.one( "click", handler );
  1139. $structure.one( "click", "p", handler );
  1140. $target.one( "click", handler );
  1141. $target[0].onclick = function( e ) {
  1142. strictEqual( e.currentTarget, this, "currentTarget at target (native handler)" );
  1143. equal( e.isTrigger, 3, "trigger at target (native handler)" );
  1144. };
  1145. $target.trigger("click");
  1146. $target.one( "click", function( e ) {
  1147. equal( e.isTrigger, 2, "triggerHandler at target" );
  1148. });
  1149. $target[0].onclick = function( e ) {
  1150. equal( e.isTrigger, 2, "triggerHandler at target (native handler)" );
  1151. };
  1152. $target.triggerHandler("click");
  1153. handler = function( e ) {
  1154. strictEqual( e.isTrigger, undefined, "native event at " + this.id );
  1155. };
  1156. $target.one( "click", handler );
  1157. $target[0].onclick = function( e ) {
  1158. strictEqual( e.isTrigger, undefined, "native event at target (native handler)" );
  1159. };
  1160. fireNative( $target[0], "click" );
  1161. });
  1162. test(".on()/.off()", function() {
  1163. expect(65);
  1164. var event, clicked, hash, called, livec, lived, livee,
  1165. submit = 0, div = 0, livea = 0, liveb = 0;
  1166. jQuery("#body").on("submit", "#qunit-fixture div", function(){ submit++; return false; });
  1167. jQuery("#body").on("click", "#qunit-fixture div", function(){ div++; });
  1168. jQuery("#body").on("click", "div#nothiddendiv", function(){ livea++; });
  1169. jQuery("#body").on("click", "div#nothiddendivchild", function(){ liveb++; });
  1170. // Nothing should trigger on the body
  1171. jQuery("body").trigger("click");
  1172. equal( submit, 0, "Click on body" );
  1173. equal( div, 0, "Click on body" );
  1174. equal( livea, 0, "Click on body" );
  1175. equal( liveb, 0, "Click on body" );
  1176. // This should trigger two events
  1177. submit = 0; div = 0; livea = 0; liveb = 0;
  1178. jQuery("div#nothiddendiv").trigger("click");
  1179. equal( submit, 0, "Click on div" );
  1180. equal( div, 1, "Click on div" );
  1181. equal( livea, 1, "Click on div" );
  1182. equal( liveb, 0, "Click on div" );
  1183. // This should trigger three events (w/ bubbling)
  1184. submit = 0; div = 0; livea = 0; liveb = 0;
  1185. jQuery("div#nothiddendivchild").trigger("click");
  1186. equal( submit, 0, "Click on inner div" );
  1187. equal( div, 2, "Click on inner div" );
  1188. equal( livea, 1, "Click on inner div" );
  1189. equal( liveb, 1, "Click on inner div" );
  1190. // This should trigger one submit
  1191. submit = 0; div = 0; livea = 0; liveb = 0;
  1192. jQuery("div#nothiddendivchild").trigger("submit");
  1193. equal( submit, 1, "Submit on div" );
  1194. equal( div, 0, "Submit on div" );
  1195. equal( livea, 0, "Submit on div" );
  1196. equal( liveb, 0, "Submit on div" );
  1197. // Make sure no other events were removed in the process
  1198. submit = 0; div = 0; livea = 0; liveb = 0;
  1199. jQuery("div#nothiddendivchild").trigger("click");
  1200. equal( submit, 0, "off Click on inner div" );
  1201. equal( div, 2, "off Click on inner div" );
  1202. equal( livea, 1, "off Click on inner div" );
  1203. equal( liveb, 1, "off Click on inner div" );
  1204. // Now make sure that the removal works
  1205. submit = 0; div = 0; livea = 0; liveb = 0;
  1206. jQuery("#body").off("click", "div#nothiddendivchild");
  1207. jQuery("div#nothiddendivchild").trigger("click");
  1208. equal( submit, 0, "off Click on inner div" );
  1209. equal( div, 2, "off Click on inner div" );
  1210. equal( livea, 1, "off Click on inner div" );
  1211. equal( liveb, 0, "off Click on inner div" );
  1212. // Make sure that the click wasn't removed too early
  1213. submit = 0; div = 0; livea = 0; liveb = 0;
  1214. jQuery("div#nothiddendiv").trigger("click");
  1215. equal( submit, 0, "off Click on inner div" );
  1216. equal( div, 1, "off Click on inner div" );
  1217. equal( livea, 1, "off Click on inner div" );
  1218. equal( liveb, 0, "off Click on inner div" );
  1219. // Make sure that stopPropagation doesn't stop live events
  1220. submit = 0; div = 0; livea = 0; liveb = 0;
  1221. jQuery("#body").on("click", "div#nothiddendivchild", function( e ){ liveb++; e.stopPropagation(); });
  1222. jQuery("div#nothiddendivchild").trigger("click");
  1223. equal( submit, 0, "stopPropagation Click on inner div" );
  1224. equal( div, 1, "stopPropagation Click on inner div" );
  1225. equal( livea, 0, "stopPropagation Click on inner div" );
  1226. equal( liveb, 1, "stopPropagation Click on inner div" );
  1227. // Make sure click events only fire with primary click
  1228. submit = 0; div = 0; livea = 0; liveb = 0;
  1229. event = jQuery.Event("click");
  1230. event.button = 1;
  1231. jQuery("div#nothiddendiv").trigger(event);
  1232. equal( livea, 0, "on secondary click" );
  1233. jQuery("#body").off("click", "div#nothiddendivchild");
  1234. jQuery("#body").off("click", "div#nothiddendiv");
  1235. jQuery("#body").off("click", "#qunit-fixture div");
  1236. jQuery("#body").off("submit", "#qunit-fixture div");
  1237. // Test binding with a different context
  1238. clicked = 0;
  1239. jQuery("#qunit-fixture").on("click", "#foo", function(){ clicked++; });
  1240. jQuery("#qunit-fixture div").trigger("click");
  1241. jQuery("#foo").trigger("click");
  1242. jQuery("#qunit-fixture").trigger("click");
  1243. jQuery("body").trigger("click");
  1244. equal( clicked, 2, "on with a context" );
  1245. // Test unbinding with a different context
  1246. jQuery("#qunit-fixture").off("click", "#foo");
  1247. jQuery("#foo").trigger("click");
  1248. equal( clicked, 2, "off with a context");
  1249. // Test binding with event data
  1250. jQuery("#body").on("click", "#foo", true, function( e ){ equal( e.data, true, "on with event data" ); });
  1251. jQuery("#foo").trigger("click");
  1252. jQuery("#body").off("click", "#foo");
  1253. // Test binding with trigger data
  1254. jQuery("#body").on("click", "#foo", function(e, data){ equal( data, true, "on with trigger data" ); });
  1255. jQuery("#foo").trigger("click", true);
  1256. jQuery("#body").off("click", "#foo");
  1257. // Test binding with different this object
  1258. jQuery("#body").on("click", "#foo", jQuery.proxy(function(){ equal( this["foo"], "bar", "on with event scope" ); }, { "foo": "bar" }));
  1259. jQuery("#foo").trigger("click");
  1260. jQuery("#body").off("click", "#foo");
  1261. // Test binding with different this object, event data, and trigger data
  1262. jQuery("#body").on("click", "#foo", true, jQuery.proxy(function(e, data){
  1263. equal( e.data, true, "on with with different this object, event data, and trigger data" );
  1264. equal( this.foo, "bar", "on with with different this object, event data, and trigger data" );
  1265. equal( data, true, "on with with different this object, event data, and trigger data");
  1266. }, { "foo": "bar" }));
  1267. jQuery("#foo").trigger("click", true);
  1268. jQuery("#body").off("click", "#foo");
  1269. // Verify that return false prevents default action
  1270. jQuery("#body").on("click", "#anchor2", function(){ return false; });
  1271. hash = window.location.hash;
  1272. jQuery("#anchor2").trigger("click");
  1273. equal( window.location.hash, hash, "return false worked" );
  1274. jQuery("#body").off("click", "#anchor2");
  1275. // Verify that .preventDefault() prevents default action
  1276. jQuery("#body").on("click", "#anchor2", function(e){ e.preventDefault(); });
  1277. hash = window.location.hash;
  1278. jQuery("#anchor2").trigger("click");
  1279. equal( window.location.hash, hash, "e.preventDefault() worked" );
  1280. jQuery("#body").off("click", "#anchor2");
  1281. // Test binding the same handler to multiple points
  1282. called = 0;
  1283. function callback(){ called++; return false; }
  1284. jQuery("#body").on("click", "#nothiddendiv", callback);
  1285. jQuery("#body").on("click", "#anchor2", callback);
  1286. jQuery("#nothiddendiv").trigger("click");
  1287. equal( called, 1, "Verify that only one click occurred." );
  1288. called = 0;
  1289. jQuery("#anchor2").trigger("click");
  1290. equal( called, 1, "Verify that only one click occurred." );
  1291. // Make sure that only one callback is removed
  1292. jQuery("#body").off("click", "#anchor2", callback);
  1293. called = 0;
  1294. jQuery("#nothiddendiv").trigger("click");
  1295. equal( called, 1, "Verify that only one click occurred." );
  1296. called = 0;
  1297. jQuery("#anchor2").trigger("click");
  1298. equal( called, 0, "Verify that no click occurred." );
  1299. // Make sure that it still works if the selector is the same,
  1300. // but the event type is different
  1301. jQuery("#body").on("foo", "#nothiddendiv", callback);
  1302. // Cleanup
  1303. jQuery("#body").off("click", "#nothiddendiv", callback);
  1304. called = 0;
  1305. jQuery("#nothiddendiv").trigger("click");
  1306. equal( called, 0, "Verify that no click occurred." );
  1307. called = 0;
  1308. jQuery("#nothiddendiv").trigger("foo");
  1309. equal( called, 1, "Verify that one foo occurred." );
  1310. // Cleanup
  1311. jQuery("#body").off("foo", "#nothiddendiv", callback);
  1312. // Make sure we don't loose the target by DOM modifications
  1313. // after the bubble already reached the liveHandler
  1314. livec = 0;
  1315. jQuery("#nothiddendivchild").html("<span></span>");
  1316. jQuery("#body").on("click", "#nothiddendivchild", function(){ jQuery("#nothiddendivchild").html(""); });
  1317. jQuery("#body").on("click", "#nothiddendivchild", function(e){ if(e.target) {livec++;} });
  1318. jQuery("#nothiddendiv span").trigger("click");
  1319. equal( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." );
  1320. equal( livec, 1, "Verify that second handler occurred even with nuked target." );
  1321. // Cleanup
  1322. jQuery("#body").off("click", "#nothiddendivchild");
  1323. // Verify that .live() occurs and cancel bubble in the same order as
  1324. // we would expect .on() and .click() without delegation
  1325. lived = 0;
  1326. livee = 0;
  1327. // bind one pair in one order
  1328. jQuery("#body").on("click", "span#liveSpan1 a", function(){ lived++; return false; });
  1329. jQuery("#body").on("click", "span#liveSpan1", function(){ livee++; });
  1330. jQuery("span#liveSpan1 a").trigger("click");
  1331. equal( lived, 1, "Verify that only one first handler occurred." );
  1332. equal( livee, 0, "Verify that second handler doesn't." );
  1333. // and one pair in inverse
  1334. jQuery("#body").on("click", "span#liveSpan2", function(){ livee++; });
  1335. jQuery("#body").on("click", "span#liveSpan2 a", function(){ lived++; return false; });
  1336. lived = 0;
  1337. livee = 0;
  1338. jQuery("span#liveSpan2 a").trigger("click");
  1339. equal( lived, 1, "Verify that only one first handler occurred." );
  1340. equal( livee, 0, "Verify that second handler doesn't." );
  1341. // Cleanup
  1342. jQuery("#body").off("click", "**");
  1343. // Test this, target and currentTarget are correct
  1344. jQuery("#body").on("click", "span#liveSpan1", function( e ) {
  1345. equal( this.id, "liveSpan1", "Check the this within a on handler" );
  1346. equal( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a on handler" );
  1347. equal( e.delegateTarget, document.body, "Check the event.delegateTarget within a on handler" );
  1348. equal( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a on handler" );
  1349. });
  1350. jQuery("span#liveSpan1 a").trigger("click");
  1351. jQuery("#body").off("click", "span#liveSpan1");
  1352. // Work with deep selectors
  1353. livee = 0;
  1354. function clickB() { livee++; }
  1355. jQuery("#body").on("click", "#nothiddendiv div", function(){ livee++; });
  1356. jQuery("#body").on("click", "#nothiddendiv div", clickB);
  1357. jQuery("#body").on("mouseover", "#nothiddendiv div", function(){ livee++; });
  1358. equal( livee, 0, "No clicks, deep selector." );
  1359. livee = 0;
  1360. jQuery("#nothiddendivchild").trigger("click");
  1361. equal( livee, 2, "Click, deep selector." );
  1362. livee = 0;
  1363. jQuery("#nothiddendivchild").trigger("mouseover");
  1364. equal( livee, 1, "Mouseover, deep selector." );
  1365. jQuery("#body").off("mouseover", "#nothiddendiv div");
  1366. livee = 0;
  1367. jQuery("#nothiddendivchild").trigger("click");
  1368. equal( livee, 2, "Click, deep selector." );
  1369. livee = 0;
  1370. jQuery("#nothiddendivchild").trigger("mouseover");
  1371. equal( livee, 0, "Mouseover, deep selector." );
  1372. jQuery("#body").off("click", "#nothiddendiv div", clickB);
  1373. livee = 0;
  1374. jQuery("#nothiddendivchild").trigger("click");
  1375. equal( livee, 1, "Click, deep selector." );
  1376. jQuery("#body").off("click", "#nothiddendiv div");
  1377. });
  1378. test("jQuery.off using dispatched jQuery.Event", function() {
  1379. expect(1);
  1380. var markup = jQuery("<p><a href='#'>target</a></p>"),
  1381. count = 0;
  1382. markup
  1383. .on( "click.name", "a", function( event ) {
  1384. equal( ++count, 1, "event called once before removal" );
  1385. jQuery().off( event );
  1386. })
  1387. .find("a").trigger("click").trigger("click").end()
  1388. .remove();
  1389. });
  1390. test( "delegated event with delegateTarget-relative selector", function() {
  1391. expect(3);
  1392. var markup = jQuery("<div><ul><li><a id=\"a0\"></a><ul id=\"ul0\"><li class=test><a id=\"a0_0\"></a></li><li><a id=\"a0_1\"></a></li></ul></li></ul></div>").appendTo("#qunit-fixture");
  1393. // Non-positional selector (#12383)
  1394. markup.find("#ul0")
  1395. .on( "click", "div li a", function() {
  1396. ok( false, "div is ABOVE the delegation point!" );
  1397. })
  1398. .on( "click", "ul a", function() {
  1399. ok( false, "ul IS the delegation point!" );
  1400. })
  1401. .on( "click", "li.test a", function() {
  1402. ok( true, "li.test is below the delegation point." );
  1403. })
  1404. .find("#a0_0").trigger("click").end()
  1405. .off("click");
  1406. // Positional selector (#11315)
  1407. markup.find("ul").eq(0)
  1408. .on( "click", ">li>a", function() {
  1409. ok( this.id === "a0", "child li was clicked" );
  1410. })
  1411. .find("#ul0")
  1412. .on( "click", "li:first>a", function() {
  1413. ok( this.id === "a0_0" , "first li under #u10 was clicked" );
  1414. })
  1415. .end()
  1416. .find("a").trigger("click").end()
  1417. .find("#ul0").off();
  1418. markup.remove();
  1419. });
  1420. test( "delegated event with selector matching Object.prototype property (#13203)", function() {
  1421. expect(1);
  1422. var matched = 0;
  1423. jQuery("#foo").on( "click", "toString", function() {
  1424. matched++;
  1425. });
  1426. jQuery("#anchor2").trigger("click");
  1427. equal( matched, 0, "Nothing matched 'toString'" );
  1428. });
  1429. test("stopPropagation() stops directly-bound events on delegated target", function() {
  1430. expect(1);
  1431. var markup = jQuery("<div><p><a href=\"#\">target</a></p></div>");
  1432. markup
  1433. .on( "click", function() {
  1434. ok( false, "directly-bound event on delegate target was called" );
  1435. })
  1436. .on( "click", "a", function( e ) {
  1437. e.stopPropagation();
  1438. ok( true, "delegated handler was called" );
  1439. })
  1440. .find("a").trigger("click").end()
  1441. .remove();
  1442. });
  1443. test("off all bound delegated events", function(){
  1444. expect(2);
  1445. var count = 0,
  1446. clicks = 0,
  1447. div = jQuery("#body");
  1448. div.on( "click submit", "div#nothiddendivchild", function(){ count++; } );
  1449. div.on( "click", function(){ clicks++; } );
  1450. div.off( undefined, "**" );
  1451. jQuery("div#nothiddendivchild").trigger("click");
  1452. jQuery("div#nothiddendivchild").trigger("submit");
  1453. equal( count, 0, "Make sure no events were triggered." );
  1454. div.trigger("click");
  1455. equal( clicks, 2, "Make sure delegated and directly bound event occurred." );
  1456. div.off("click");
  1457. });
  1458. test("on with multiple delegated events", function(){
  1459. expect(1);
  1460. var count = 0,
  1461. div = jQuery("#body");
  1462. div.on("click submit", "div#nothiddendivchild", function(){ count++; });
  1463. jQuery("div#nothiddendivchild").trigger("click");
  1464. jQuery("div#nothiddendivchild").trigger("submit");
  1465. equal( count, 2, "Make sure both the click and submit were triggered." );
  1466. jQuery("#body").off( undefined, "**" );
  1467. });
  1468. test("delegated on with change", function(){
  1469. expect(8);
  1470. var select, checkbox, checkboxFunction,
  1471. text, textChange, oldTextVal,
  1472. password, passwordChange, oldPasswordVal,
  1473. selectChange = 0,
  1474. checkboxChange = 0;
  1475. select = jQuery("select[name='S1']");
  1476. jQuery("#body").on("change", "select[name='S1']", function() {
  1477. selectChange++;
  1478. });
  1479. checkbox = jQuery("#check2");
  1480. checkboxFunction = function(){
  1481. checkboxChange++;
  1482. };
  1483. jQuery("#body").on("change", "#check2", checkboxFunction);
  1484. // test click on select
  1485. // second click that changed it
  1486. selectChange = 0;
  1487. select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
  1488. select.trigger("change");
  1489. equal( selectChange, 1, "Change on click." );
  1490. // test keys on select
  1491. selectChange = 0;
  1492. select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
  1493. select.trigger("change");
  1494. equal( selectChange, 1, "Change on keyup." );
  1495. // test click on checkbox
  1496. checkbox.trigger("change");
  1497. equal( checkboxChange, 1, "Change on checkbox." );
  1498. // test blur/focus on text
  1499. text = jQuery("#name");
  1500. textChange = 0;
  1501. oldTextVal = text.val();
  1502. jQuery("#body").on("change", "#name", function() {
  1503. textChange++;
  1504. });
  1505. text.val(oldTextVal+"foo");
  1506. text.trigger("change");
  1507. equal( textChange, 1, "Change on text input." );
  1508. text.val(oldTextVal);
  1509. jQuery("#body").off("change", "#name");
  1510. // test blur/focus on password
  1511. password = jQuery("#name");
  1512. passwordChange = 0;
  1513. oldPasswordVal = password.val();
  1514. jQuery("#body").on("change", "#name", function() {
  1515. passwordChange++;
  1516. });
  1517. password.val(oldPasswordVal + "foo");
  1518. password.trigger("change");
  1519. equal( passwordChange, 1, "Change on password input." );
  1520. password.val(oldPasswordVal);
  1521. jQuery("#body").off("change", "#name");
  1522. // make sure die works
  1523. // die all changes
  1524. selectChange = 0;
  1525. jQuery("#body").off("change", "select[name='S1']");
  1526. select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
  1527. select.trigger("change");
  1528. equal( selectChange, 0, "Die on click works." );
  1529. selectChange = 0;
  1530. select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
  1531. select.trigger("change");
  1532. equal( selectChange, 0, "Die on keyup works." );
  1533. // die specific checkbox
  1534. jQuery("#body").off("change", "#check2", checkboxFunction);
  1535. checkbox.trigger("change");
  1536. equal( checkboxChange, 1, "Die on checkbox." );
  1537. });
  1538. test("delegated on with submit", function() {
  1539. expect( 2 );
  1540. var count1 = 0, count2 = 0;
  1541. jQuery("#body").on("submit", "#testForm", function(ev) {
  1542. count1++;
  1543. ev.preventDefault();
  1544. });
  1545. jQuery(document).on("submit", "body", function(ev) {
  1546. count2++;
  1547. ev.preventDefault();
  1548. });
  1549. jQuery("#testForm input[name=sub1]").trigger("submit");
  1550. equal( count1, 1, "Verify form submit." );
  1551. equal( count2, 1, "Verify body submit." );
  1552. jQuery("#body").off( undefined, "**" );
  1553. jQuery(document).off( undefined, "**" );
  1554. });
  1555. test("delegated off() with only namespaces", function() {
  1556. expect(2);
  1557. var $delegate = jQuery("#liveHandlerOrder"),
  1558. count = 0;
  1559. $delegate.on("click.ns", "a", function() {
  1560. count++;
  1561. });
  1562. jQuery("a", $delegate).eq(0).trigger("click.ns");
  1563. equal( count, 1, "delegated click.ns");
  1564. $delegate.off( ".ns", "**" );
  1565. jQuery("a", $delegate).eq(1).trigger("click.ns");
  1566. equal( count, 1, "no more .ns after off");
  1567. });
  1568. test("Non DOM element events", function() {
  1569. expect(1);
  1570. var o = {};
  1571. jQuery(o).on("nonelementobj", function() {
  1572. ok( true, "Event on non-DOM object triggered" );
  1573. });
  1574. jQuery(o).trigger("nonelementobj");
  1575. });
  1576. test("inline handler returning false stops default", function() {
  1577. expect(1);
  1578. var markup = jQuery("<div><a href=\"#\" onclick=\"return false\">x</a></div>");
  1579. markup.on( "click", function(e) {
  1580. ok( e.isDefaultPrevented(), "inline handler prevented default");
  1581. return false;
  1582. });
  1583. markup.find("a").trigger("click");
  1584. markup.off("click");
  1585. });
  1586. test("window resize", function() {
  1587. expect(2);
  1588. jQuery(window).off();
  1589. jQuery(window).on( "resize", function(){
  1590. ok( true, "Resize event fired." );
  1591. }).trigger("resize").off("resize");
  1592. ok( !jQuery._data(window, "events"), "Make sure all the events are gone." );
  1593. });
  1594. test("focusin bubbles", function() {
  1595. expect(2);
  1596. var input = jQuery( "<input type='text' />" ).prependTo( "body" ),
  1597. order = 0;
  1598. // focus the element so DOM focus won't fire
  1599. input[0].focus();
  1600. jQuery( "body" ).on( "focusin.focusinBubblesTest", function(){
  1601. equal( 1, order++, "focusin on the body second" );
  1602. });
  1603. input.on( "focusin.focusinBubblesTest", function(){
  1604. equal( 0, order++, "focusin on the element first" );
  1605. });
  1606. // Removed since DOM focus is unreliable on test swarm
  1607. // DOM focus method
  1608. // input[0].focus();
  1609. // To make the next focus test work, we need to take focus off the input.
  1610. // This will fire another focusin event, so set order to reflect that.
  1611. // order = 1;
  1612. // jQuery("#text1")[0].focus();
  1613. // jQuery trigger, which calls DOM focus
  1614. order = 0;
  1615. input.trigger( "focus" );
  1616. input.remove();
  1617. jQuery( "body" ).off( "focusin.focusinBubblesTest" );
  1618. });
  1619. test("custom events with colons (#3533, #8272)", function() {
  1620. expect(1);
  1621. var tab = jQuery("<table><tr><td>trigger</td></tr></table>").appendTo("body");
  1622. try {
  1623. tab.trigger("back:forth");
  1624. ok( true, "colon events don't throw" );
  1625. } catch ( e ) {
  1626. ok( false, "colon events die" );
  1627. }
  1628. tab.remove();
  1629. });
  1630. test(".on and .off", function() {
  1631. expect(9);
  1632. var counter, mixfn, data,
  1633. $onandoff = jQuery("<div id=\"onandoff\"><p>on<b>and</b>off</p><div>worked<em>or</em>borked?</div></div>").appendTo("body");
  1634. // Simple case
  1635. jQuery( "#onandoff" )
  1636. .on( "whip", function() {
  1637. ok( true, "whipped it good" );
  1638. })
  1639. .trigger( "whip" )
  1640. .off();
  1641. // Direct events only
  1642. counter = 0;
  1643. jQuery( "#onandoff b" )
  1644. .on( "click", 5, function( e, trig ) {
  1645. counter += e.data + (trig || 9); // twice, 5+9+5+17=36
  1646. })
  1647. .one( "click", 7, function( e, trig ) {
  1648. counter += e.data + (trig || 11); // once, 7+11=18
  1649. })
  1650. .trigger("click")
  1651. .trigger( "click", 17 )
  1652. .off( "click" );
  1653. equal( counter, 54, "direct event bindings with data" );
  1654. // Delegated events only
  1655. counter = 0;
  1656. jQuery( "#onandoff" )
  1657. .on( "click", "em", 5, function( e, trig ) {
  1658. counter += e.data + (trig || 9); // twice, 5+9+5+17=36
  1659. })
  1660. .one( "click", "em", 7, function( e, trig ) {
  1661. counter += e.data + (trig || 11); // once, 7+11=18
  1662. })
  1663. .find("em")
  1664. .trigger("click")
  1665. .trigger( "click", 17 )
  1666. .end()
  1667. .off( "click", "em" );
  1668. equal( counter, 54, "delegated event bindings with data" );
  1669. // Mixed event bindings and types
  1670. counter = 0;
  1671. mixfn = function(e, trig) {
  1672. counter += (e.data || 0) + (trig || 1);
  1673. };
  1674. jQuery( "#onandoff" )
  1675. .on( " click clack cluck ", "em", 2, mixfn )
  1676. .on( "cluck", "b", 7, mixfn )
  1677. .on( "cluck", mixfn )
  1678. .trigger( "what!" )
  1679. .each( function() {
  1680. equal( counter, 0, "nothing triggered yet" );
  1681. })
  1682. .find( "em" )
  1683. .one( "cluck", 3, mixfn )
  1684. .trigger( "cluck", 8 ) // 3+8 2+8 + 0+8 = 29
  1685. .off()
  1686. .trigger( "cluck", 9 ) // 2+9 + 0+9 = 20
  1687. .end()
  1688. .each( function() {
  1689. equal( counter, 49, "after triggering em element" );
  1690. })
  1691. .off( "cluck", function(){} ) // shouldn't remove anything
  1692. .trigger( "cluck", 2 ) // 0+2 = 2
  1693. .each( function() {
  1694. equal( counter, 51, "after triggering #onandoff cluck" );
  1695. })
  1696. .find( "b" )
  1697. .on( "click", 95, mixfn )
  1698. .on( "clack", "p", 97, mixfn )
  1699. .one( "cluck", 3, mixfn )
  1700. .trigger( "quack", 19 ) // 0
  1701. .off( "click clack cluck" )
  1702. .end()
  1703. .each( function() {
  1704. equal( counter, 51, "after triggering b" );
  1705. })
  1706. .trigger( "cluck", 3 ) // 0+3 = 3
  1707. .off( "clack", "em", mixfn )
  1708. .find( "em" )
  1709. .trigger( "clack" ) // 0
  1710. .end()
  1711. .each( function() {
  1712. equal( counter, 54, "final triggers" );
  1713. })
  1714. .off( "click cluck" );
  1715. // We should have removed all the event handlers ... kinda hacky way to check this
  1716. data = jQuery.data[ jQuery( "#onandoff" )[0].expando ] || {};
  1717. equal( data["events"], undefined, "no events left" );
  1718. $onandoff.remove();
  1719. });
  1720. test("special on name mapping", function() {
  1721. expect( 7 );
  1722. jQuery.event.special["slap"] = {
  1723. bindType: "click",
  1724. delegateType: "swing",
  1725. handle: function( event ) {
  1726. equal( event.handleObj.origType, "slap", "slapped your mammy, " + event.type );
  1727. }
  1728. };
  1729. var comeback = function( event ) {
  1730. ok( true, "event " + event.type + " triggered" );
  1731. };
  1732. jQuery("<div><button id=\"mammy\">Are We Not Men?</button></div>")
  1733. .on( "slap", "button", jQuery.noop )
  1734. .on( "swing", "button", comeback )
  1735. .find( "button" )
  1736. .on( "slap", jQuery.noop )
  1737. .on( "click", comeback )
  1738. .trigger( "click" ) // bindType-slap and click
  1739. .off( "slap" )
  1740. .trigger( "click" ) // click
  1741. .off( "click" )
  1742. .trigger( "swing" ) // delegateType-slap and swing
  1743. .end()
  1744. .off( "slap swing", "button" )
  1745. .find( "button" ) // everything should be gone
  1746. .trigger( "slap" )
  1747. .trigger( "click" )
  1748. .trigger( "swing" )
  1749. .end()
  1750. .remove();
  1751. delete jQuery.event.special["slap"];
  1752. jQuery.event.special["gutfeeling"] = {
  1753. bindType: "click",
  1754. delegateType: "click",
  1755. handle: function( event ) {
  1756. equal( event.handleObj.origType, "gutfeeling", "got a gutfeeling" );
  1757. // Need to call the handler since .one() uses it to unbind
  1758. return event.handleObj.handler.call( this , event );
  1759. }
  1760. };
  1761. // Ensure a special event isn't removed by its mapped type
  1762. jQuery( "<p>Gut Feeling</p>" )
  1763. .on( "click", jQuery.noop )
  1764. .on( "gutfeeling", jQuery.noop )
  1765. .off( "click" )
  1766. .trigger( "gutfeeling" )
  1767. .remove();
  1768. // Ensure special events are removed when only a namespace is provided
  1769. jQuery( "<p>Gut Feeling</p>" )
  1770. .on( "gutfeeling.Devo", jQuery.noop )
  1771. .off( ".Devo" )
  1772. .trigger( "gutfeeling" )
  1773. .remove();
  1774. // Ensure .one() events are removed after their maiden voyage
  1775. jQuery( "<p>Gut Feeling</p>" )
  1776. .one( "gutfeeling", jQuery.noop )
  1777. .trigger( "gutfeeling" ) // This one should
  1778. .trigger( "gutfeeling" ) // This one should not
  1779. .remove();
  1780. delete jQuery.event.special["gutfeeling"];
  1781. });
  1782. test(".on and .off, selective mixed removal (#10705)", function() {
  1783. expect(7);
  1784. var timingx = function( e ) {
  1785. ok( true, "triggered " + e.type );
  1786. };
  1787. jQuery( "<p>Strange Pursuit</p>" )
  1788. .on( "click", timingx )
  1789. .on( "click.duty", timingx )
  1790. .on( "click.now", timingx )
  1791. .on( "devo", timingx )
  1792. .on( "future", timingx )
  1793. .trigger( "click" ) // 3
  1794. .trigger( "devo" ) // 1
  1795. .off( ".duty devo " ) // trailing space
  1796. .trigger( "future" ) // 1
  1797. .trigger( "click" ) // 2
  1798. .off( "future click" )
  1799. .trigger( "click" ); // 0
  1800. });
  1801. test(".on( event-map, null-selector, data ) #11130", function() {
  1802. expect( 1 );
  1803. var $p = jQuery("<p>Strange Pursuit</p>"),
  1804. data = "bar",
  1805. map = {
  1806. "foo": function( event ) {
  1807. equal( event.data, "bar", "event.data correctly relayed with null selector" );
  1808. $p.remove();
  1809. }
  1810. };
  1811. $p.on( map, null, data ).trigger("foo");
  1812. });
  1813. test("clone() delegated events (#11076)", function() {
  1814. expect(3);
  1815. var counter = { "center": 0, "fold": 0, "centerfold": 0 },
  1816. clicked = function() {
  1817. counter[ jQuery(this).text().replace(/\s+/, "") ]++;
  1818. },
  1819. table =
  1820. jQuery( "<table><tr><td>center</td><td>fold</td></tr></table>" )
  1821. .on( "click", "tr", clicked )
  1822. .on( "click", "td:first-child", clicked )
  1823. .on( "click", "td:last-child", clicked ),
  1824. clone = table.clone( true );
  1825. clone.find("td").trigger("click");
  1826. equal( counter["center"], 1, "first child" );
  1827. equal( counter["fold"], 1, "last child" );
  1828. equal( counter["centerfold"], 2, "all children" );
  1829. table.remove();
  1830. clone.remove();
  1831. });
  1832. test("checkbox state (#3827)", function() {
  1833. expect( 9 );
  1834. var markup = jQuery("<div><input type=checkbox><div>").appendTo("#qunit-fixture"),
  1835. cb = markup.find("input")[0];
  1836. jQuery(cb).on( "click", function(){
  1837. equal( this.checked, false, "just-clicked checkbox is not checked" );
  1838. });
  1839. markup.on( "click", function(){
  1840. equal( cb.checked, false, "checkbox is not checked in bubbled event" );
  1841. });
  1842. // Native click
  1843. cb.checked = true;
  1844. equal( cb.checked, true, "native - checkbox is initially checked" );
  1845. cb.click();
  1846. equal( cb.checked, false, "native - checkbox is no longer checked" );
  1847. // jQuery click
  1848. cb.checked = true;
  1849. equal( cb.checked, true, "jQuery - checkbox is initially checked" );
  1850. jQuery( cb ).trigger("click");
  1851. equal( cb.checked, false, "jQuery - checkbox is no longer checked" );
  1852. // Handlers only; checkbox state remains false
  1853. jQuery( cb ).triggerHandler( "click" );
  1854. });
  1855. test("focus-blur order (#12868)", function() {
  1856. expect( 5 );
  1857. var order,
  1858. $text = jQuery("#text1"),
  1859. $radio = jQuery("#radio1").trigger("focus");
  1860. // IE6-10 fire focus/blur events asynchronously; this is the resulting mess.
  1861. // IE's browser window must be topmost for this to work properly!!
  1862. stop();
  1863. $radio[0].focus();
  1864. setTimeout( function() {
  1865. $text
  1866. .on( "focus", function(){
  1867. equal( order++, 1, "text focus" );
  1868. })
  1869. .on( "blur", function(){
  1870. equal( order++, 0, "text blur" );
  1871. });
  1872. $radio
  1873. .on( "focus", function(){
  1874. equal( order++, 1, "radio focus" );
  1875. })
  1876. .on( "blur", function(){
  1877. equal( order++, 0, "radio blur" );
  1878. });
  1879. // Enabled input getting focus
  1880. order = 0;
  1881. equal( document.activeElement, $radio[0], "radio has focus" );
  1882. $text.trigger("focus");
  1883. setTimeout( function() {
  1884. equal( document.activeElement, $text[0], "text has focus" );
  1885. // Run handlers without native method on an input
  1886. order = 1;
  1887. $radio.triggerHandler( "focus" );
  1888. start();
  1889. }, 50 );
  1890. }, 50 );
  1891. });
  1892. test("hover event no longer special since 1.9", function() {
  1893. expect( 1 );
  1894. jQuery("<div>craft</div>")
  1895. .on( "hover", function( e ) {
  1896. equal( e.type, "hover", "I am hovering!" );
  1897. })
  1898. .trigger("hover")
  1899. .off("hover");
  1900. });
  1901. test("fixHooks extensions", function() {
  1902. expect( 2 );
  1903. // IE requires focusable elements to be visible, so append to body
  1904. var $fixture = jQuery( "<input type='text' id='hook-fixture' />" ).appendTo( "body" ),
  1905. saved = jQuery.event.fixHooks.click;
  1906. // Ensure the property doesn't exist
  1907. $fixture.on( "click", function( event ) {
  1908. ok( !("blurrinessLevel" in event), "event.blurrinessLevel does not exist" );
  1909. });
  1910. fireNative( $fixture[0], "click" );
  1911. $fixture.off( "click" );
  1912. jQuery.event.fixHooks.click = {
  1913. filter: function( event ) {
  1914. event.blurrinessLevel = 42;
  1915. return event;
  1916. }
  1917. };
  1918. // Trigger a native click and ensure the property is set
  1919. $fixture.on( "click", function( event ) {
  1920. equal( event.blurrinessLevel, 42, "event.blurrinessLevel was set" );
  1921. });
  1922. fireNative( $fixture[0], "click" );
  1923. delete jQuery.event.fixHooks.click;
  1924. $fixture.off( "click" ).remove();
  1925. jQuery.event.fixHooks.click = saved;
  1926. });
  1927. testIframeWithCallback( "jQuery.ready promise", "event/promiseReady.html", function( isOk ) {
  1928. expect(1);
  1929. ok( isOk, "$.when( $.ready ) works" );
  1930. });
  1931. testIframeWithCallback( "Focusing iframe element", "event/focusElem.html", function( isOk ) {
  1932. expect(1);
  1933. ok( isOk, "Focused an element in an iframe" );
  1934. });
  1935. // need PHP here to make the incepted IFRAME hang
  1936. if ( hasPHP ) {
  1937. testIframeWithCallback( "jQuery.ready synchronous load with long loading subresources", "event/syncReady.html", function( isOk ) {
  1938. expect(1);
  1939. ok( isOk, "jQuery loaded synchronously fires ready when the DOM can truly be interacted with" );
  1940. });
  1941. }
  1942. (function(){
  1943. // This code must be run before DOM ready!
  1944. var notYetReady, noEarlyExecution,
  1945. order = [],
  1946. args = {};
  1947. notYetReady = !jQuery.isReady;
  1948. test("jQuery.isReady", function() {
  1949. expect(2);
  1950. equal(notYetReady, true, "jQuery.isReady should not be true before DOM ready");
  1951. equal(jQuery.isReady, true, "jQuery.isReady should be true once DOM is ready");
  1952. });
  1953. // Create an event handler.
  1954. function makeHandler( testId ) {
  1955. // When returned function is executed, push testId onto `order` array
  1956. // to ensure execution order. Also, store event handler arg to ensure
  1957. // the correct arg is being passed into the event handler.
  1958. return function( arg ) {
  1959. order.push(testId);
  1960. args[testId] = arg;
  1961. };
  1962. }
  1963. // Bind to the ready event in every possible way.
  1964. jQuery(makeHandler("a"));
  1965. jQuery(document).ready(makeHandler("b"));
  1966. jQuery(document).on("ready.readytest", makeHandler("c"));
  1967. // Do it twice, just to be sure.
  1968. jQuery(makeHandler("d"));
  1969. jQuery(document).ready(makeHandler("e"));
  1970. jQuery(document).on("ready.readytest", makeHandler("f"));
  1971. noEarlyExecution = order.length === 0;
  1972. // This assumes that QUnit tests are run on DOM ready!
  1973. test("jQuery ready", function() {
  1974. expect(10);
  1975. ok(noEarlyExecution, "Handlers bound to DOM ready should not execute before DOM ready");
  1976. // Ensure execution order.
  1977. deepEqual(order, ["a", "b", "d", "e", "c", "f"], "Bound DOM ready handlers should execute in on-order, but those bound with jQuery(document).on( 'ready', fn ) will always execute last");
  1978. // Ensure handler argument is correct.
  1979. equal(args["a"], jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery");
  1980. equal(args["b"], jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery");
  1981. ok(args["c"] instanceof jQuery.Event, "Argument passed to fn in jQuery(document).on( 'ready', fn ) should be an event object");
  1982. order = [];
  1983. // Now that the ready event has fired, again bind to the ready event
  1984. // in every possible way. These event handlers should execute immediately.
  1985. jQuery(makeHandler("g"));
  1986. equal(order.pop(), "g", "Event handler should execute immediately");
  1987. equal(args["g"], jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery");
  1988. jQuery(document).ready(makeHandler("h"));
  1989. equal(order.pop(), "h", "Event handler should execute immediately");
  1990. equal(args["h"], jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery");
  1991. jQuery(document).on("ready.readytest", makeHandler("never"));
  1992. equal(order.length, 0, "Event handler should never execute since DOM ready has already passed");
  1993. // Cleanup.
  1994. jQuery(document).off("ready.readytest");
  1995. });
  1996. })();
  1997. test("change handler should be detached from element", function() {
  1998. expect( 2 );
  1999. var $fixture = jQuery( "<input type='text' id='change-ie-leak' />" ).appendTo( "body" ),
  2000. originRemoveEvent = jQuery.removeEvent,
  2001. wrapperRemoveEvent = function(elem, type, handle){
  2002. equal("change", type, "Event handler for 'change' event should be removed");
  2003. equal("change-ie-leak", jQuery(elem).attr("id"), "Event handler for 'change' event should be removed from appropriate element");
  2004. originRemoveEvent(elem, type, handle);
  2005. };
  2006. jQuery.removeEvent = wrapperRemoveEvent ;
  2007. $fixture.on( "change", function() {});
  2008. $fixture.off( "change" );
  2009. $fixture.remove();
  2010. jQuery.removeEvent = originRemoveEvent;
  2011. });
  2012. asyncTest("trigger click on checkbox, fires change event", function() {
  2013. expect(1);
  2014. var check = jQuery("#check2");
  2015. check.on( "change", function() {
  2016. // get it?
  2017. check.off("change");
  2018. ok( true, "Change event fired as a result of triggered click" );
  2019. start();
  2020. }).trigger("click");
  2021. });
  2022. test( "Namespace preserved when passed an Event (#12739)", function() {
  2023. expect( 4 );
  2024. var markup = jQuery(
  2025. "<div id='parent'><div id='child'></div></div>"
  2026. ),
  2027. triggered = 0,
  2028. fooEvent;
  2029. markup.find("div")
  2030. .addBack()
  2031. .on( "foo.bar", function( e ) {
  2032. if ( !e.handled ) {
  2033. triggered++;
  2034. e.handled = true;
  2035. equal( e.namespace, "bar", "namespace is bar" );
  2036. jQuery( e.target ).find("div").each(function() {
  2037. jQuery( this ).triggerHandler( e );
  2038. });
  2039. }
  2040. })
  2041. .on( "foo.bar2", function() {
  2042. ok( false, "foo.bar2 called on trigger " + triggered + " id " + this.id );
  2043. });
  2044. markup.trigger("foo.bar");
  2045. markup.trigger( jQuery.Event("foo.bar") );
  2046. fooEvent = jQuery.Event("foo");
  2047. fooEvent.namespace = "bar";
  2048. markup.trigger( fooEvent );
  2049. markup.remove();
  2050. equal( triggered, 3, "foo.bar triggered" );
  2051. });
  2052. test( "make sure events cloned correctly", 18, function() {
  2053. var clone,
  2054. fixture = jQuery("#qunit-fixture"),
  2055. checkbox = jQuery("#check1"),
  2056. p = jQuery("#firstp");
  2057. fixture.on( "click change", function( event, result ) {
  2058. ok( result, event.type + " on original element is fired" );
  2059. }).on( "click", "#firstp", function( event, result ) {
  2060. ok( result, "Click on original child element though delegation is fired" );
  2061. }).on( "change", "#check1", function( event, result ) {
  2062. ok( result, "Change on original child element though delegation is fired" );
  2063. });
  2064. p.on("click", function() {
  2065. ok( true, "Click on original child element is fired" );
  2066. });
  2067. checkbox.on("change", function() {
  2068. ok( true, "Change on original child element is fired" );
  2069. });
  2070. fixture.clone().trigger("click").trigger("change"); // 0 events should be fired
  2071. clone = fixture.clone( true );
  2072. clone.find("p").eq(0).trigger( "click", true ); // 3 events should fire
  2073. clone.find("#check1").trigger( "change", true ); // 3 events should fire
  2074. clone.remove();
  2075. clone = fixture.clone( true, true );
  2076. clone.find("p").eq(0).trigger( "click", true ); // 3 events should fire
  2077. clone.find("#check1").trigger( "change", true ); // 3 events should fire
  2078. fixture.off();
  2079. p.off();
  2080. checkbox.off();
  2081. p.trigger("click"); // 0 should be fired
  2082. checkbox.trigger("change"); // 0 should be fired
  2083. clone.find("p").eq(0).trigger( "click", true ); // 3 events should fire
  2084. clone.find("#check1").trigger( "change", true ); // 3 events should fire
  2085. clone.remove();
  2086. clone.find("p").eq(0).trigger("click"); // 0 should be fired
  2087. clone.find("#check1").trigger("change"); // 0 events should fire
  2088. });
  2089. test( "Check order of focusin/focusout events", 2, function() {
  2090. var focus, blur,
  2091. input = jQuery("#name");
  2092. input.on("focus", function() {
  2093. focus = true;
  2094. }).on("focusin", function() {
  2095. ok( !focus, "Focusin event should fire before focus does" );
  2096. }).on("blur", function() {
  2097. blur = true;
  2098. }).on("focusout", function() {
  2099. ok( !blur, "Focusout event should fire before blur does" );
  2100. });
  2101. // gain focus
  2102. input.trigger("focus");
  2103. // then lose it
  2104. jQuery("#search").trigger("focus");
  2105. // cleanup
  2106. input.off();
  2107. });
  2108. test( "String.prototype.namespace does not cause trigger() to throw (#13360)", function() {
  2109. expect( 1 );
  2110. var errored = false;
  2111. String.prototype.namespace = function() {};
  2112. try {
  2113. jQuery("<p>").trigger("foo.bar");
  2114. } catch( e ) {
  2115. errored = true;
  2116. }
  2117. equal( errored, false, "trigger() did not throw exception" );
  2118. delete String.prototype.namespace;
  2119. });