轉:https://segmentfault.com/a/1190000005362826前端
前端框架 Avalon
有一個問題,即 在使用 ms-duplex 後,此 input 在 Windows 8.1 的 IE11 下沒法正常使用輸入法輸入中文
,這個問題在 Avalon 1.5.X 中一直存在且被複現。segmentfault
既然沒法直接修復,那麼就使用 avalon.directive
自定義一個新的指令來簡單地處理雙向數據綁定。起名爲 ms-model
,名字來源於 Angular
.數組
avalon.directive("model", { init: function (binding) { // binding 爲指令初始化時注入對象. init(binding)(); }, // 此方法相似 Get / Set, 在控制器使用 $watch 監視 (binding.expr, 即 ms-model="expr") 時觸發, 可在此作一些雜七雜八的事情. update: function (newVal, oldVal) { // this 爲 init 中的 bingding 對象. this.element.value = newVal; } }); // Definition: ms-model. function init (binding) { var thisElement = binding.element; // 指令所在的節點. var directiveValue = binding.expr; // 指令綁定的屬性. var imeIgnored = false; // 輸入法忽略控制標識. // 初始化賦值. 必須推入任務隊列才生效. setTimeout(function () { thisElement.value = binding.oldValue !== undefined ? binding.oldValue : ""; // 未賦值進行清空, 防止 IE / Edge 緩存. }, 1); // Definition: Input 事件. var inputEvent = function (event) { if (imeIgnored) { return; } // vmodels 是指令所在的控制器的數組, 看起來是按照 [孫, 子, 父] 的冒泡順序排序, 但未確定. // ms-duplex 只處理了指令所在的最近的控制器的數值, 在此也只處理 vmodels[0]. eval('binding.vmodels[0].' + directiveValue + ' = thisElement.value;'); // 使用 eval 解決多層嵌套問題. }; return function () { // 在使用輸入法的時候不進行數據同步. // 進入輸入法狀態時鎖定控制標識. avalon.bind(thisElement, "compositionstart", function () { imeIgnored = true; }); // 輸入法恢復時釋放控制標識. avalon.bind(thisElement, "compositionend", function () { imeIgnored = false; inputEvent(); // Fixing for Edge, Edge 的日語輸入法的 input 事件在 compositionend 以前執行, 而其餘瀏覽器包括 IE11 全是 compositionend 以後, 須要手動觸發一次. }); // 設置 Input 事件. avalon.bind(thisElement, "input", inputEvent, false); // 修復 IE 問題. if (window.ScriptEngine && window.ScriptEngine()) { // 修復 IE9 的 Backspace / Delete 剪切不觸發 Input 事件的問題. if (navigator.appVersion.indexOf("MSIE 9.0") > -1) { avalon.bind(thisElement, "cut", function () { setTimeout(inputEvent, 1); // 必須推入任務隊列中執行才生效. }); } // IE 額外註冊 KeyUp 進行數據綁定來避免輸入法無效的問題. avalon.bind(thisElement, "keyup", function (event) { event = event || window.event; if (event.keyCode === 17 || event.keyCode === 18 || event.ctrlKey || event.shiftKey || event.altKey) { return; } inputEvent(); }); } } }