Fieldset和禁用所有子输入 - 解决IE问题

时间:2014-06-09 11:27:04

标签: angularjs internet-explorer angularjs-directive fieldset disabled-input

我有一个在其下面有ui-view的字段集 每个视图都有很多字段(字段是包含输入的指令)。

它看起来像这样:

<fieldset ng-disabled='myCondition'>
   <div ui-view></div> // this changes with lot's of fields that look like <div field='text-box'></div>
</fieldset>

现在,这非常有用,所有浏览器上的字段都被禁用除了IE
我做了一些谷歌,看到即不支持fieldset + disabled,我正在寻找一个快速的解决方法。

我尝试了一些接近但不完美的事情,我认为我不是第一个需要解决方案的人(即使我没有在谷歌上找到任何东西)。

5 个答案:

答案 0 :(得分:8)

似乎与IE问题相关,请参阅this及相关内容(抱歉,还不能发布超过2个链接)。 第一个将在下一个主要IE版本(Edge?)中修复。 第二个仍然开放。

我怀疑,问题是用户仍然可以点击禁用字段集内的输入进行编辑。

如果是这样,那么只有&#34; css&#34; IE 8+的解决方法,在禁用的字段集上方创建透明覆盖,以防止单击字段集。

Microsoft Connect问题中描述了解决方法。

fiddle,用于演示解决方法。

fieldset {
    /* to set absolute position for :after content */
    position: relative;
}
/* this will 'screen' all fieldset content from clicks */
fieldset[disabled]:after {

    content: ' ';
    position: absolute;
    z-index: 1;
    top: 0; right: 0; bottom: 0; left: 0;
    /* i don't know... it was necessary to set background */
    background: url( data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==);
}

解决方法有一些限制,请参阅代码以了解详细信息。

JavaScript有一些选项。

似乎对于IE9 +,您可以捕获fieldset上的mousedown事件,如果禁用了fieldset,则调用e.preventDefault()。

fieldset.onmousedown = function(e) {

    if (!e) e = window.event;

    if (fieldset.disabled) {

        // for IE9+
        if (e.preventDefault) {

            e.preventDefault();
        }
        // for IE8-
        else {

            // actualy does not work
            //e.returnValue = false;
        }

        return false;
    }
}

对于IE8及以下版本,在禁用的字段集上捕获冒泡的mousedown事件是不可能的,甚至不会调用事件处理程序。但是可以在documetn.body上找到它们在fieldset祖先上的例子。但同样,对于IE8-你不能通过阻止mousedown事件的默认动作来防止元素被聚焦。有关详细信息,请参阅jQuery ticket#10345(抱歉,无法发布超过2个链接)。您可以尝试使用UNSELECTABLE属性来临时禁止元素获得焦点。像这样:

document.body.onmousedown = function(e) {

    if (!e) e = window.event;

    var target = e.target || e.srcElement;

    if (fieldset.contains(target) && fieldset.disabled) {

        // no need to do this on body!!! do it on fieldset itself
        /*if (e.preventDefault) {

            e.preventDefault();
        }
        else {*/

            // this is useless
            //e.returnValue = false;

            // but this works
            fieldset.setAttribute("UNSELECTABLE", "on");

            window.setTimeout(function() { target.setAttribute("UNSELECTABLE", ""); },4);
        /*}*/

        return false;
    }
}

答案 1 :(得分:6)

  

现在有一个解决方案。

虽然Microsoft documentation状态为fixed但问题仍未解决!

但是,现在我们也可以使用pointer-events: none;。它将禁用所有输入元素

fieldset[disabled] {
    pointer-events: none;
}

答案 2 :(得分:2)

我遇到了完全相同的问题,我想出了这个指令:

angular.module('module').directive('fieldset', function () {
    return {
        restrict: 'E',
        link: function (scope, element, attrs) {

            if (angular.isUndefined(element.prop('disabled'))) { //only watch if the browser doesn't support disabled on fieldsets
                scope.$watch(function () { return element.attr('disabled'); }, function (disabled) {
                    element.find('input, select, textarea').prop('disabled', disabled)
                });
            }
        }
    }
});

虽然功能检测存在缺陷。在IE上,看来fieldset元素(它看起来实际上是所有元素)都被禁用了#c;属性设置为false。

编辑:我刚刚意识到它在一个&#39; ng-view&#39;中。你可能不得不乱用$ timeouts来让它在视图加载后应用更改。或者,更简单的是,将fieldset放在视图中。

答案 3 :(得分:1)

这是在IE11中禁用字段集的修复: https://connect.microsoft.com/IE/feedbackdetail/view/962368/can-still-edit-input-type-text-within-fieldset-disabled

检测IE: Detecting IE11 using CSS Capability/Feature Detection

_:-ms-lang(x), fieldset[disabled].ie10up 
        {
            pointer-events: none;
            opacity: .65;
        }

答案 4 :(得分:1)

正如其他浏览器在“禁用”字段上的悬停处显示(disabled(/))符号一样,因此此更改仅应应用于使用@media的IE。

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
             fieldset[disabled] {
                 pointer-events: none;
                 }
            }