【问题标题】:angularjs ng-change doesn't get fired on ng-model-onblur directive in IE9 and 10angularjs ng-change 不会在 IE9 和 10 中的 ng-model-onblur 指令上触发
【发布时间】:2014-10-04 20:27:28
【问题描述】:

我有一个带有 ng-model-on-blur 指令(从 Angularjs: input[text] ngChange fires while the value is changing 复制)的输入文本框,并附加了一个 ng-change 事件处理程序。当用户开箱即用时,它会触发附加到 ng-change 的函数。我修改了链接函数,因此它也绑定了更改和粘贴事件。

link: function(scope, elm, attr, ngModelCtrl) {
        if (attr.type === 'radio' || attr.type === 'checkbox') return;

        if($sniffer.hasEvent('input')){
            elm.unbind('input').unbind('keydown').unbind('change').unbind('paste');
        }
        else if($sniffer.hasEvent('change')){
            elm.unbind('input').unbind('keydown').unbind('change').unbind('paste');
        }
        //IE8 doesn't recognize the input or change events and throws error on unbind input.
        else{
            elm.unbind('keydown').unbind('change').unbind('paste');
        }
        elm.bind('blur change paste', function() {
            scope.$apply(function() {
                ngModelCtrl.$setViewValue(elm.val());
            });
        });
    }

我在该页面上有一个按钮,它打开一个弹出页面,用户可以在其中输入内容,然后将值传输回父页面上的输入文本框。在大多数其他浏览器(Chrome、Firefox、Safari,甚至 IE8..)中,当从弹出窗口接收到输入文本框的数据时会触发 ng-change,但在 IE9 和 10 中,不会触发 ng-change从弹出窗口接收数据。当用户在字段外键入时,该指令调用 ng-change 函数,手动粘贴数据或通过右键单击文本框,但是当数据来自弹出窗口时,它不会触发该函数。

弹出窗口不使用AngularJS,而是使用窗口对象的opener属性将值传递给输入文本框。

任何帮助将不胜感激!

【问题讨论】:

  • 从弹出窗口更新文本框中的值后,我使用 IE9 脚本控制台检查了范围变量的值。当文本框显示一个值时, angular.element(document.getElementById('name')).scope().name 产生“”。我签入了 Chrome 开发工具,并且在父级从弹出窗口接收到值时更新了范围值。

标签: javascript angularjs internet-explorer angularjs-ng-change


【解决方案1】:

由于从父页面元素的弹出页面触发更改事件的方式,我能够解决该问题。设置 opener.parentElement.value = newValue; 后的弹出页面如果 document.createEventObject 为真,则执行 parentElement.fireEvent('change'),否则为非 IE 浏览器执行 parentElement.dispatchEvent()。

MS 在 IE9 中引入了 DOM Level 2 事件,因此在 IE >=9 浏览器中不支持 fireEvent。由于 IE>=9 的 document.createEventObject 仍然为 true,因此它正在执行 fireEvent,因此在我的指令 elm.bind('change') 中没有被触发。我将弹出的 javascript 文件更改为:

if(element.dispatchEvent) {
    //IE >= 9 and other browsers event code
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent(event, true, true );
    return element.dispatchEvent(evt);
}
else if(element.fireEvent){
    //IE < 9
    var evt = document.createEventObject();
    return element.fireEvent('on'+event,evt);
}

并且 ng-change 也开始为 IE >= 9 触发。这篇Why does .fireEvent() not work in IE9? 的帖子帮助我理解并解决了问题。

再次感谢这个很棒的社区!

【讨论】:

  • 我在解决了 ng-change 问题后遇到了另一个问题。该页面还为 datepicker 小部件使用 Prototype 1.6 javascript 库,并使用 Event.observe(parentElement, 'change', callback) 来更新其他字段。问题是对于 IE9 和 10,dispatchEvent 会触发 parentElement 上的 ng-change,但 Event.observe 内部的回调没有触发,这会导致页面上出现其他问题。非常感谢有人提供帮助,以便 Prototype 的事件系统和 AngularJS 可以很好地发挥作用。
猜你喜欢
  • 1970-01-01
  • 2016-12-09
  • 2015-03-08
  • 2015-05-05
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多