使用 AngularJS 绑定处理 IE 的清除按钮
Handling IE's clear button with AngularJS binding
IE 在每个文本输入中都有一个 "X" 将清除输入。但是,当单击此按钮时,它会清除文本框,但不会更新输入绑定到的 Angular 模型。
<input type="text" ng-model="name" />
有关行为的示例,请参阅 http://jsfiddle.net/p5x1zwr9/。
有关该行为的视频,请参阅 http://youtu.be/LFaEwliTzpQ。
我正在使用 IE 11。
编辑:似乎确实有一个 Knockout 的解决方案,但我不知道如何将它应用到 AngularJS:Handle IE 9 & 10's clear button with Knockout binding
更新:Jonathan Sampson 帮助我意识到这实际上适用于 1.3.6 之前的 AngularJS 版本,所以这可能是一个新的 Angular错误。
更新:未解决的问题:https://github.com/angular/angular.js/issues/11193
输入表单中的 X 按钮是 IE10+ 原生的,您无法对其进行任何操作,只能使用 CSS:
隐藏它
input[type=text]::-ms-clear {
display: none;
}
然后您可以创建自己的指令来模仿这种行为。只需创建一个跨度,将其放置在输入内部并向其添加 ng-click,这将清除输入的模型值。
我想出的解决方案虽然不会像删除 X 和实施您自己的解决方案那样立即更新模型,但它确实解决了我需要的问题。我所做的只是添加 ng-model-options 以包含模糊。因此,当输入模糊时,它会更新范围值。
<input type="text" ng-model="name" ng-model-options="{ updateOn: 'default blur'}" />
我为输入文本元素创建了这个 Angular 指令,它在单击清除 ('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);
});
}
}
});
感谢这个答案 (Event fired when clearing text input on IE10 with clear icon) 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=text' 在搜索 fields.By 中使用 'type=search' 这样做只有标记为 'type=search' 的输入不会有 'X' 但其他输入仍然会有 'X'这是 IE 中许多其他字段所必需的。
input[type=search]::-ms-clear {
display: none;
}
<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);
});
IE 在每个文本输入中都有一个 "X" 将清除输入。但是,当单击此按钮时,它会清除文本框,但不会更新输入绑定到的 Angular 模型。
<input type="text" ng-model="name" />
有关行为的示例,请参阅 http://jsfiddle.net/p5x1zwr9/。
有关该行为的视频,请参阅 http://youtu.be/LFaEwliTzpQ。
我正在使用 IE 11。
编辑:似乎确实有一个 Knockout 的解决方案,但我不知道如何将它应用到 AngularJS:Handle IE 9 & 10's clear button with Knockout binding
更新:Jonathan Sampson 帮助我意识到这实际上适用于 1.3.6 之前的 AngularJS 版本,所以这可能是一个新的 Angular错误。
更新:未解决的问题:https://github.com/angular/angular.js/issues/11193
输入表单中的 X 按钮是 IE10+ 原生的,您无法对其进行任何操作,只能使用 CSS:
隐藏它input[type=text]::-ms-clear {
display: none;
}
然后您可以创建自己的指令来模仿这种行为。只需创建一个跨度,将其放置在输入内部并向其添加 ng-click,这将清除输入的模型值。
我想出的解决方案虽然不会像删除 X 和实施您自己的解决方案那样立即更新模型,但它确实解决了我需要的问题。我所做的只是添加 ng-model-options 以包含模糊。因此,当输入模糊时,它会更新范围值。
<input type="text" ng-model="name" ng-model-options="{ updateOn: 'default blur'}" />
我为输入文本元素创建了这个 Angular 指令,它在单击清除 ('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);
});
}
}
});
感谢这个答案 (Event fired when clearing text input on IE10 with clear icon) 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=text' 在搜索 fields.By 中使用 'type=search' 这样做只有标记为 'type=search' 的输入不会有 'X' 但其他输入仍然会有 'X'这是 IE 中许多其他字段所必需的。
input[type=search]::-ms-clear {
display: none;
}
<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);
});