【问题标题】:Handling IE's clear button with AngularJS binding使用 AngularJS 绑定处理 IE 的清除按钮
【发布时间】:2015-04-22 16:29:52
【问题描述】:

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 帮助我意识到这实际上在 AngularJS 1.3.6 之前的版本中有效,所以这可能是一个新的 Angular 错误。

更新:打开的问题:https://github.com/angular/angular.js/issues/11193

【问题讨论】:

  • 这是否在 jsfiddle 外部复制?如果在 jsfiddle 中加载 Angular 1.2.1 就没有问题:jsfiddle.net/p5x1zwr9/1.
  • 它确实在 jsfiddle 之外复制,这就是我们最初发现它的方式。我们正在构建的应用程序使用 Angular 1.3.8,这就是我加载该版本的原因。
  • 看起来这种行为在 1.3.6 中被破坏了。
  • 同意,刚刚测试过。可能需要向 Angular 团队提交错误。

标签: angularjs internet-explorer


【解决方案1】:

输入表单中的 X 按钮是 IE10+ 原生的,你不能对它做任何事情,只能用 CSS 隐藏它:

input[type=text]::-ms-clear {
   display: none;
}

然后您可以创建自己的指令来模仿这种行为。只需创建一个跨度,将其放置在输入内并添加 ng-click 即可,这将清除输入的模型值。

【讨论】:

  • Knockout 似乎有解决方案,但我不知道如何将其应用于 AngularJS:stackoverflow.com/questions/16421463/…
  • Lach:这是一个非常好的解决方法,谢谢。在我确认没有办法让 X 按钮真正起作用之前,还没有标记为答案。它在 AngularJS 1.2.1 中工作并在 1.3.6 中中断。
  • 是的,但是当您可以快速编写适用于所有浏览器的指令时,为什么要浪费时间尝试只在 IE 上运行。
  • 说实话,我不明白这与 Angular.js 有什么关系。这是原生 IE11 行为。
  • 保持简单。只是隐藏它。不要破解某些东西,所以角度开始对这种事件做出反应,因为您的用户没有获得真正的价值。
【解决方案2】:

我为输入文本元素创建了这个 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 代码检测到清除按钮的点击。

【讨论】:

    【解决方案3】:

    我能够使用以下指令解决此问题 - 源自上面 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');
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      使用 CSS 隐藏时 在搜索字段中使用 'type=search' 而不是 'type=text' IE 中的字段。

      input[type=search]::-ms-clear {
         display: none;
      }
      

      【讨论】:

        【解决方案5】:
        <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);
        
        });
        

        【讨论】:

          【解决方案6】:

          我想出的解决方案虽然没有像删除 X 并实施您自己的解决方案那样立即更新模型,但它确实解决了我需要的问题。我所做的只是添加 ng-model-options 以包含模糊。所以当输入模糊时,它会更新范围值。

          <input type="text" ng-model="name" ng-model-options="{ updateOn: 'default blur'}"  />
          

          【讨论】:

          • 它对我不起作用。我已经围绕本机输入元素构建了一个包装器并添加了此指令,但模型根本没有更新。
          猜你喜欢
          • 2013-05-01
          • 1970-01-01
          • 2021-10-02
          • 2017-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多