1 /** 2 * @fileOverview inspired by yui3 3 * Synthetic event that fires when the <code>value</code> property of an input 4 * field or textarea changes as a result of a keystroke, mouse operation, or 5 * input method editor (IME) input event. 6 * 7 * Unlike the <code>onchange</code> event, this event fires when the value 8 * actually changes and not when the element loses focus. This event also 9 * reports IME and multi-stroke input more reliably than <code>oninput</code> or 10 * the various key events across browsers. 11 * 12 * @author yiminghe@gmail.com 13 */ 14 KISSY.add('event/valuechange', function (S, Event, DOM, special) { 15 var VALUE_CHANGE = "valuechange", 16 getNodeName = DOM.nodeName, 17 KEY = "event/valuechange", 18 HISTORY_KEY = KEY + "/history", 19 POLL_KEY = KEY + "/poll", 20 interval = 50; 21 22 function clearPollTimer(target) { 23 if (DOM.hasData(target, POLL_KEY)) { 24 var poll = DOM.data(target, POLL_KEY); 25 clearTimeout(poll); 26 DOM.removeData(target, POLL_KEY); 27 } 28 } 29 30 function stopPoll(target) { 31 DOM.removeData(target, HISTORY_KEY); 32 clearPollTimer(target); 33 } 34 35 function stopPollHandler(ev) { 36 clearPollTimer(ev.target); 37 } 38 39 function checkChange(target) { 40 var v = target.value, 41 h = DOM.data(target, HISTORY_KEY); 42 if (v !== h) { 43 // 只触发自己绑定的 handler 44 Event.fire(target, VALUE_CHANGE, { 45 prevVal:h, 46 newVal:v 47 }, true); 48 DOM.data(target, HISTORY_KEY, v); 49 } 50 } 51 52 function startPoll(target) { 53 if (DOM.hasData(target, POLL_KEY)) { 54 return; 55 } 56 DOM.data(target, POLL_KEY, setTimeout(function () { 57 checkChange(target); 58 DOM.data(target, POLL_KEY, setTimeout(arguments.callee, interval)); 59 }, interval)); 60 } 61 62 function startPollHandler(ev) { 63 var target = ev.target; 64 // when focus ,record its current value immediately 65 if (ev.type == "focus") { 66 DOM.data(target, HISTORY_KEY, target.value); 67 } 68 startPoll(target); 69 } 70 71 function webkitSpeechChangeHandler(e) { 72 checkChange(e.target); 73 } 74 75 function monitor(target) { 76 unmonitored(target); 77 Event.on(target, "blur", stopPollHandler); 78 // fix #94 79 // see note 2012-02-08 80 Event.on(target, "webkitspeechchange", webkitSpeechChangeHandler); 81 Event.on(target, "mousedown keyup keydown focus", startPollHandler); 82 } 83 84 function unmonitored(target) { 85 stopPoll(target); 86 Event.remove(target, "blur", stopPollHandler); 87 Event.remove(target, "webkitspeechchange", webkitSpeechChangeHandler); 88 Event.remove(target, "mousedown keyup keydown focus", startPollHandler); 89 } 90 91 special[VALUE_CHANGE] = { 92 setup:function () { 93 var target = this, nodeName = getNodeName(target); 94 if (nodeName == "input" || nodeName == "textarea") { 95 monitor(target); 96 } 97 }, 98 tearDown:function () { 99 var target = this; 100 unmonitored(target); 101 } 102 }; 103 return Event; 104 }, { 105 requires:["./base", "dom", "./special"] 106 }); 107 108 /** 109 * 2012-02-08 yiminghe@gmail.com note about webkitspeechchange : 110 * 当 input 没焦点立即点击语音 111 * -> mousedown -> blur -> focus -> blur -> webkitspeechchange -> focus 112 * 第二次: 113 * -> mousedown -> blur -> webkitspeechchange -> focus 114 **/