问题
I have an input text box with a ng-model-on-blur directive(copied from Angularjs: input[text] ngChange fires while the value is changing) with a ng-change event handler attached to it. It works great as in when the user types out of the box it fires the function attached to ng-change. I modified the link function so it also binds on change and paste events.
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());
});
});
}
I have a button on that page which opens a popup page from where a user can enter something and then transfer the value back to the input text box on the parent page. In most of the other browsers(Chrome, Firefox, Safari, even IE8..) the ng-change is fired when the data is received from the popup to the input text box but in IE9 and 10 ng-change isn't fired when data is received from popup. The directive is calling the ng-change function when user types out of the field, manually pastes the data or through right click on the text box but when the data is coming from the popup it doesn't fire the function.
The popup doesn't use AngularJS but opener property of the window object to transfer the value to the input text box.
Any help would be greatly appreciated!
回答1:
I was able to solve the issue because of the way the change event was triggered from the popup page on the parent page element. The popup page after setting opener.parentElement.value = newValue; was executing parentElement.fireEvent('change') if document.createEventObject was true, else it was executing parentElement.dispatchEvent() for non-IE browsers.
MS introduced DOM Level 2 events with IE9 and hence fireEvent was not being supported in IE >=9 browsers. Since document.createEventObject was still true for IE>=9 it was executing fireEvent and hence in my directive elm.bind('change') was not getting triggered. I changed my popup javascript file to:
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);
}
and ng-change began triggering for IE >= 9 also. This post Why does .fireEvent() not work in IE9? helped me in understanding the problem and solving it.
Thanks to this awesome community again!
来源:https://stackoverflow.com/questions/25252949/angularjs-ng-change-doesnt-get-fired-on-ng-model-onblur-directive-in-ie9-and-10