Fieldset и отключение всех дочерних входов - обходной путь для IE

У меня есть набор полей, в котором есть представление пользовательского интерфейса.
В каждом представлении было много полей (поле — это директива, которая оборачивает ввод) под ним.

Это выглядит примерно так:

<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, и я ищу быстрый обходной путь.

Я пробовал некоторые вещи, которые были близки, но не идеальны, и я предполагаю, что я не первый, кому нужно решение (хотя я ничего не нашел в Google).


person Amir Popovich    schedule 09.06.2014    source источник


Ответы (5)


Теперь у него есть 1-строчное решение.

.

Хотя статус fixed в Документация Microsoft Проблема все еще не решена!

Но теперь мы также можем использовать pointer-events: none;. Это отключит все элементы ввода

fieldset[disabled] {
    pointer-events: none;
}
person Saurabh Bayani    schedule 29.05.2017
comment
Этот. Сэкономил мне время, так как мне не пришлось писать обходной путь JS или что-то в этом роде. - person Pieter VDE; 21.02.2018
comment
Связанная страница больше не существует. - person marines; 21.12.2018

Похоже, что это связано с проблемами IE, см. это и похожие (извините, пока нельзя опубликовать более двух ссылок). Первый будет исправлен в следующем крупном выпуске IE (Edge?). Второй еще открыт.

Как я подозреваю, проблема в том, что пользователь по-прежнему может нажимать на входы внутри отключенных полей и редактировать их.

Если это так, существует обходной путь «только css» для IE 8+, который создает прозрачное наложение над отключенным набором полей, что предотвращает щелчок по набору полей.

Обходной путь описан в проблемах Microsoft Connect.

Существует скрипта, демонстрирующая обходной путь в действии.

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+ вы можете перехватывать события mousedown в наборе полей и вызывать 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 при отключенном наборе полей, обработчики событий даже не вызываются. Но их можно поймать на предках fieldset, например, на documetn.body. Но опять же, для IE8 вы не можете предотвратить фокусировку элемента, предотвратив действие по умолчанию события mousedown. Подробности см. в тикете jQuery № 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;
    }
}
person ylepikhov    schedule 14.08.2015
comment
css отлично работает. Я бы также добавил курсор, запрещенный для отключенного набора полей. fieldset[disabled] {курсор: не разрешено; } - person duyn9uyen; 28.01.2016
comment
Большое спасибо! Вы спасли мой день. - person tarekahf; 20.10.2016
comment
z-index: 1 слишком мало при использовании вместе с загрузочным CSS. например .input-group.form-control и многие другие стили располагаются на z-индексе 2, 3 и выше. он отлично работает с z-index из 10 - person girafi; 04.01.2017

У меня была точно такая же проблема, и я придумал эту директиву:

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 (все элементы, кажется, на самом деле) имеют свойство «отключено», для которого просто установлено значение false.

Редактировать: я только что понял, что он находится внутри «ng-view». Возможно, вам придется возиться с $timeouts, чтобы применить изменения после загрузки представления. Или, что еще проще, поместите набор полей внутрь представления.

person Iain    schedule 24.06.2014

Это исправление для отключения наборов полей в IE11: https://connect.microsoft.com/IE/feedbackdetail/view/962368/can-still-edit-input-type-text-within-fieldset-disabled

Обнаружение IE: Обнаружение IE11 с помощью CSS Capability/Feature Detection

_:-ms-lang(x), fieldset[disabled].ie10up 
        {
            pointer-events: none;
            opacity: .65;
        }
person Chris Lamothe    schedule 07.12.2017
comment
‹класс набора полей=ie10up › - person Chris Lamothe; 07.12.2017

Поскольку другой браузер показывает (отключенный (/)) символ при наведении для отключенного поля, поэтому это изменение мы должны применять только к IE, используя @media

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