1 /** 2 * @fileOverview change bubble and checkbox/radio fix patch for ie<9 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("event/change", function (S, UA, Event, DOM, special) { 6 var mode = S.Env.host.document['documentMode']; 7 8 if (UA['ie'] && (UA['ie'] < 9 || (mode && mode < 9))) { 9 10 var rformElems = /^(?:textarea|input|select)$/i; 11 12 function isFormElement(n) { 13 return rformElems.test(n.nodeName); 14 } 15 16 function isCheckBoxOrRadio(el) { 17 var type = el.type; 18 return type == "checkbox" || type == "radio"; 19 } 20 21 special['change'] = { 22 setup:function () { 23 var el = this; 24 if (isFormElement(el)) { 25 // checkbox/radio only fires change when blur in ie<9 26 // so use another technique from jquery 27 if (isCheckBoxOrRadio(el)) { 28 // change in ie<9 29 // change = propertychange -> click 30 Event.on(el, "propertychange", propertyChange); 31 Event.on(el, "click", onClick); 32 } else { 33 // other form elements use native , do not bubble 34 return false; 35 } 36 } else { 37 // if bind on parentNode ,lazy bind change event to its form elements 38 // note event order : beforeactivate -> change 39 // note 2: checkbox/radio is exceptional 40 Event.on(el, "beforeactivate", beforeActivate); 41 } 42 }, 43 tearDown:function () { 44 var el = this; 45 if (isFormElement(el)) { 46 if (isCheckBoxOrRadio(el)) { 47 Event.remove(el, "propertychange", propertyChange); 48 Event.remove(el, "click", onClick); 49 } else { 50 return false; 51 } 52 } else { 53 Event.remove(el, "beforeactivate", beforeActivate); 54 S.each(DOM.query("textarea,input,select", el), function (fel) { 55 if (fel.__changeHandler) { 56 fel.__changeHandler = 0; 57 Event.remove(fel, "change", {fn:changeHandler, last:1}); 58 } 59 }); 60 } 61 } 62 }; 63 64 function propertyChange(e) { 65 if (e.originalEvent.propertyName == "checked") { 66 this.__changed = 1; 67 } 68 } 69 70 function onClick(e) { 71 if (this.__changed) { 72 this.__changed = 0; 73 // fire from itself 74 Event.fire(this, "change", e); 75 } 76 } 77 78 function beforeActivate(e) { 79 var t = e.target; 80 if (isFormElement(t) && !t.__changeHandler) { 81 t.__changeHandler = 1; 82 // lazy bind change , always as last handler among user's handlers 83 Event.on(t, "change", {fn:changeHandler, last:1}); 84 } 85 } 86 87 function changeHandler(e) { 88 var fel = this; 89 90 if ( 91 // in case stopped by user's callback,same with submit 92 // http://bugs.jquery.com/ticket/11049 93 // see : test/change/bubble.html 94 e.isPropagationStopped || 95 // checkbox/radio already bubble using another technique 96 isCheckBoxOrRadio(fel)) { 97 return; 98 } 99 var p; 100 if (p = fel.parentNode) { 101 // fire from parent , itself is handled natively 102 Event.fire(p, "change", e); 103 } 104 } 105 106 } 107 }, { 108 requires:["ua", "./base", "dom", './special'] 109 });