处理IE';s带AngularJS绑定的清除按钮
IE在每个文本输入中都有一个“X”,用于清除输入。但是,单击此按钮时,在清除文本框的同时,不会更新输入绑定到的角度模型处理IE';s带AngularJS绑定的清除按钮,angularjs,internet-explorer,Angularjs,Internet Explorer,IE在每个文本输入中都有一个“X”,用于清除输入。但是,单击此按钮时,在清除文本框的同时,不会更新输入绑定到的角度模型 <input type="text" ng-model="name" /> 有关该行为的示例,请参见 有关该行为的视频,请参阅 我正在使用IE11 编辑:似乎有一个击倒的解决方案,但我不知道如何将其应用于AngularJS: 更新:Jonathan Sampson帮助我认识到这实际上在AngularJS 1.3.6之前的版本中有效,因此这可能是一个新的角度错误
<input type="text" ng-model="name" />
有关该行为的示例,请参见
有关该行为的视频,请参阅
我正在使用IE11
编辑:似乎有一个击倒的解决方案,但我不知道如何将其应用于AngularJS: 更新:Jonathan Sampson帮助我认识到这实际上在AngularJS 1.3.6之前的版本中有效,因此这可能是一个新的角度错误
更新:已打开的问题:输入表单中的X按钮是IE10+的本机按钮,您对此无能为力,只能使用CSS隐藏它:
input[type=text]::-ms-clear {
display: none;
}
然后您可以创建自己的指令来模拟这种行为。只需创建一个跨距,将其放置在输入中,然后单击添加ng,这将清除输入的模型值。我提出的解决方案不会像删除X并实现自己的解决方案那样立即更新模型,但它确实解决了我需要的问题。我所做的就是添加ng模型选项以包括模糊。因此,当输入模糊时,它将更新范围值
<input type="text" ng-model="name" ng-model-options="{ updateOn: 'default blur'}" />
我为输入文本元素创建了这个角度指令,当单击clear('X')按钮时,它会手动调用元素的change()事件。这解决了我们项目上的问题。我希望它能帮助别人
angular.module('app')
.directive('input', function () {
return {
restrict: 'E',
scope: {},
link: function (scope, elem, attrs) {
// Only care about textboxes, not radio, checkbox, etc.
var validTypes = /^(search|email|url|tel|number|text)$/i;
if (!validTypes.test(attrs.type)) return;
// Bind to the mouseup event of the input textbox.
elem.bind('mouseup', function () {
// Get the old value (before click) and return if it's already empty
// as there's nothing to do.
var $input = $(this), oldValue = $input.val();
if (oldValue === '') return;
// Check new value after click, and if it's now empty it means the
// clear button was clicked. Manually trigger element's change() event.
setTimeout(function () {
var newValue = $input.val();
if (newValue === '') {
angular.element($input).change();
}
}, 1);
});
}
}
});
多亏了这个答案(),JavaScript代码检测到了清除按钮点击。我能够使用下面的指令解决这个问题-来自上面0x783e的答案。它可以与angular的更高版本提供更好的兼容性。除了ng change之外,它还应该与$watches或解析器一起工作
angular
.module('yourModuleName')
.directive('input', FixIEClearButton);
FixIEClearButton.$inject = ['$timeout', '$sniffer'];
function FixIEClearButton($timeout, $sniffer) {
var directive = {
restrict: 'E',
require: '?ngModel',
link: Link,
controller: function () { }
};
return directive;
function Link(scope, elem, attr, controller) {
var type = elem[0].type;
//ie11 doesn't seem to support the input event, at least according to angular
if (type !== 'text' || !controller || $sniffer.hasEvent('input')) {
return;
}
elem.on("mouseup", function (event) {
var oldValue = elem.val();
if (oldValue == "") {
return;
}
$timeout(function () {
var newValue = elem.val();
if (newValue !== oldValue) {
elem.val(oldValue);
elem.triggerHandler('keydown');
elem.val(newValue);
elem.triggerHandler('focus');
}
}, 0, false);
});
scope.$on('$destroy', destroy);
elem.on('$destroy', destroy);
function destroy() {
elem.off('mouseup');
}
}
}
在使用CSS隐藏时
在搜索字段中使用“type=search”代替“type=text”。这样做,只有标记为“type=search”的输入才不会有“X”,但其他输入仍会有“X”,这是IE中许多其他字段所必需的
input[type=search]::-ms-clear {
display: none;
}
这个解决方案对我有效
$(“#搜索”).bind(“mouseup”,函数(e){
变量$input=$(此),
oldValue=$input.val();
如果(oldValue==“”)返回;
//单击“清除”按钮后触发此事件时
//值尚未清除。我们必须等待它。
setTimeout(函数(){
var newValue=$input.val();
如果(newValue==“”){
$scope.name=“”;
$scope.$apply();
}
}, 1);
});
似乎有一个击倒的解决方案,但我不知道如何将它应用到AngularJS:Lach:这是一个非常好的解决方法,谢谢。直到我确认没有办法让X按钮真正起作用,我才把它标记为答案。它在AngularJS 1.2.1中起作用,在1.3.6中起作用。是的,但为什么要浪费时间让事情只在IE上起作用呢?如果你能快速编写一个指令,它可以在所有浏览器上运行。老实说,我不明白这与Angular.js有什么关系。这是IE11的固有行为。保持简单。把它藏起来。不要攻击某些东西,所以开始对此类事件做出反应,因为用户没有获得任何真正的价值。这会在JSFIDLE之外重新编程吗?如果在JSFIDLE中加载Angular 1.2.1,则没有问题:。它在JSFIDLE之外进行重新编程,这就是我们最初发现它的方式。我们正在构建的应用程序使用Angular 1.3.8,这就是我加载该版本的原因。看起来这种行为在1.3.6中有所突破。同意,只是测试了一下。可能需要向Angular团队提交一个bug。它对我不起作用。我已经围绕本机输入元素构建了一个包装器,并添加了这个指令,但是模型根本没有更新。
<input type="text" ng-model="name" id="search" />
This solution works for me
$("#search").bind("mouseup", function(e){
var $input = $(this),
oldValue = $input.val();
if (oldValue == "") return;
// When this event is fired after clicking on the clear button
// the value is not cleared yet. We have to wait for it.
setTimeout(function(){
var newValue = $input.val();
if (newValue == ""){
$scope.name="";
$scope.$apply();
}
}, 1);
});