github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/themes/wind/static/libs/vue-1.0.24/src/directives/public/model/text.js (about) 1 /* global jQuery */ 2 3 import { 4 isIE9, 5 isAndroid, 6 toNumber, 7 _toString, 8 nextTick, 9 debounce as _debounce 10 } from '../../../util/index' 11 12 export default { 13 14 bind () { 15 var self = this 16 var el = this.el 17 var isRange = el.type === 'range' 18 var lazy = this.params.lazy 19 var number = this.params.number 20 var debounce = this.params.debounce 21 22 // handle composition events. 23 // http://blog.evanyou.me/2014/01/03/composition-event/ 24 // skip this for Android because it handles composition 25 // events quite differently. Android doesn't trigger 26 // composition events for language input methods e.g. 27 // Chinese, but instead triggers them for spelling 28 // suggestions... (see Discussion/#162) 29 var composing = false 30 if (!isAndroid && !isRange) { 31 this.on('compositionstart', function () { 32 composing = true 33 }) 34 this.on('compositionend', function () { 35 composing = false 36 // in IE11 the "compositionend" event fires AFTER 37 // the "input" event, so the input handler is blocked 38 // at the end... have to call it here. 39 // 40 // #1327: in lazy mode this is unecessary. 41 if (!lazy) { 42 self.listener() 43 } 44 }) 45 } 46 47 // prevent messing with the input when user is typing, 48 // and force update on blur. 49 this.focused = false 50 if (!isRange && !lazy) { 51 this.on('focus', function () { 52 self.focused = true 53 }) 54 this.on('blur', function () { 55 self.focused = false 56 // do not sync value after fragment removal (#2017) 57 if (!self._frag || self._frag.inserted) { 58 self.rawListener() 59 } 60 }) 61 } 62 63 // Now attach the main listener 64 this.listener = this.rawListener = function () { 65 if (composing || !self._bound) { 66 return 67 } 68 var val = number || isRange 69 ? toNumber(el.value) 70 : el.value 71 self.set(val) 72 // force update on next tick to avoid lock & same value 73 // also only update when user is not typing 74 nextTick(function () { 75 if (self._bound && !self.focused) { 76 self.update(self._watcher.value) 77 } 78 }) 79 } 80 81 // apply debounce 82 if (debounce) { 83 this.listener = _debounce(this.listener, debounce) 84 } 85 86 // Support jQuery events, since jQuery.trigger() doesn't 87 // trigger native events in some cases and some plugins 88 // rely on $.trigger() 89 // 90 // We want to make sure if a listener is attached using 91 // jQuery, it is also removed with jQuery, that's why 92 // we do the check for each directive instance and 93 // store that check result on itself. This also allows 94 // easier test coverage control by unsetting the global 95 // jQuery variable in tests. 96 this.hasjQuery = typeof jQuery === 'function' 97 if (this.hasjQuery) { 98 const method = jQuery.fn.on ? 'on' : 'bind' 99 jQuery(el)[method]('change', this.rawListener) 100 if (!lazy) { 101 jQuery(el)[method]('input', this.listener) 102 } 103 } else { 104 this.on('change', this.rawListener) 105 if (!lazy) { 106 this.on('input', this.listener) 107 } 108 } 109 110 // IE9 doesn't fire input event on backspace/del/cut 111 if (!lazy && isIE9) { 112 this.on('cut', function () { 113 nextTick(self.listener) 114 }) 115 this.on('keyup', function (e) { 116 if (e.keyCode === 46 || e.keyCode === 8) { 117 self.listener() 118 } 119 }) 120 } 121 122 // set initial value if present 123 if ( 124 el.hasAttribute('value') || 125 (el.tagName === 'TEXTAREA' && el.value.trim()) 126 ) { 127 this.afterBind = this.listener 128 } 129 }, 130 131 update (value) { 132 this.el.value = _toString(value) 133 }, 134 135 unbind () { 136 var el = this.el 137 if (this.hasjQuery) { 138 const method = jQuery.fn.off ? 'off' : 'unbind' 139 jQuery(el)[method]('change', this.listener) 140 jQuery(el)[method]('input', this.listener) 141 } 142 } 143 }