资讯专栏INFORMATION COLUMN

新建指令避开 Avalon 的 ms-duplex 的问题

Ajian / 411人阅读

摘要:前端框架有一个问题,即在使用后,此在的下无法正常使用输入法输入中文,这个问题在中一直存在且被复现。既然无法直接修复,那么就使用自定义一个新的指令来简单地处理双向数据绑定。

前端框架 Avalon 有一个问题,即 在使用 ms-duplex 后,此 input 在 Windows 8.1 的 IE11 下无法正常使用输入法输入中文,这个问题在 Avalon 1.5.X 中一直存在且被复现。

既然无法直接修复,那么就使用 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();
            });

        }
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79593.html

相关文章

  • avalon与masonry结合

    摘要:相关组件版本最近,在公司的项目中,要开发一个使用瀑布流的前台,衡量了各种解决方案后,还是觉得最成熟,所以就选用了它。测试的结果很令人沮丧,依然没有控制节点的位置,所以应该不是这个问题。 相关组件版本:avalon 1.3.6、masonry 3.1.5 最近,在公司的项目中,要开发一个使用瀑布流的前台,衡量了各种解决方案后,还是觉得masonry最成熟,所以就选用了它。而在之前开发后台...

    Kosmos 评论0 收藏0
  • avalon2.1.16发布

    摘要:也是一个版本,没有增加任何新特征。不同的是内部源码已经全部用重新编写了。之前使用风格的编写,进行合并。很好的解决这问题。随着对的大胆尝试的成功,以后源码也计划随迁移。不过,大家放心,最后出来的框架还是形式,能运行于下。 avalon2.1.16也是一个Fix BUG版本,没有增加任何新特征。不同的是内部源码已经全部用es6 modules重新编写了。之前使用nodejs风格的Commo...

    oysun 评论0 收藏0
  • avalon2初体验

    摘要:最近因项目进展需求对现有项目进行重构,由于目前项目还未实现真正意义上的前后端分离后续会循序重构实现,在时间紧产品循序迭代的情况下,想一次性实现前后端分离精力实在有限主要是前端开发人力不足。 最近因项目进展需求对现有项目进行重构,由于目前项目还未实现真正意义上的前后端分离(后续会循序重构实现),在时间紧产品循序迭代的情况下,想一次性实现前后端分离精力实在有限(主要是前端开发人力不足)。所...

    youkede 评论0 收藏0
  • 吐槽专用

    摘要:最终选择了兼容到的,终于使用上框架,虽然它只是个。没有对比就没有伤害本来想着技术栈统一,移动端也准备使用。于是,之后对移动端的技术选型上更加慎重了,最终采用了文档更漂亮的。易用还真不易用,坑还真多。 吐槽 avalon.js 历史背景 需求重大调整,所有业务推倒重来(pc端主要任务涉及管理后台类型的网站); 开发周期很紧,过年前要上线; 公司pc端业务要求兼容到ie8; 2015年前...

    zxhaaa 评论0 收藏0
  • avalon 单页面程序 (种子工程)之一 用requirejs引入avalon

    摘要:现在微软终于痛定思痛决定放弃了不支持的安全更新,对我们前端来说,真的是重大利好啊言归正传,这篇文章的目的就是把怎么用构建一个单页面程序介绍以下,是对自己的一个总结,也喜欢对大家有一定的借鉴作用,写的不好不对的地方希望大家多评论评论谢谢。 这篇文章是写在公司项目结束之后的,因为我个人不太会把没有实践过的东西写出来,实践是检验真理的唯一标准么,用的怎么样,好不好用,在成熟实践过的项目上能体...

    solocoder 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<