JavaScript, разрешить пользователю сосредоточиться только на определенных элементах страницы?

В jQuery-UI-Dialog я могу отображать «модальное» диалоговое окно на моей веб-странице, так что пользователь должен щелкнуть параметр в диалоговом окне, чтобы продолжить.

Я пишу свой собственный код диалогового окна, но есть кое-что, что делает jQuery-UI-Dialog, но я пока не знаю, как это сделать.

Я могу отобразить элемент «маска» за диалоговым окном, чтобы пользователь не нажимал на элементы на странице, но пользователь все равно может выбирать элементы за диалоговым окном с помощью клавиши табуляции.

Кажется, что jQuery-UI-Dialog каким-то образом перехватывает ввод с клавиатуры внутри диалогового окна, даже когда нажата клавиша табуляции. Это очень аккуратно, но я добавлю, что этим можно злоупотреблять.

К какому аспекту DOM мне нужно получить доступ, чтобы получить эту функциональность?


person Vivian River    schedule 12.08.2011    source источник
comment
Я задавал тот же вопрос ранее. Получил отличный ответ: stackoverflow.com/questions/6296447/   -  person Jonathan M    schedule 13.08.2011


Ответы (3)


В пользовательском интерфейсе jQuery они захватывают вкладки, игнорируя другие клавиши, и ограничивают последовательность вкладок только элементами вкладок в диалоговом окне. См. фрагмент в исходном коде jQuery UI v1. .8.5:

        uiDialog.bind('keypress.ui-dialog', function(event) {
            if (event.keyCode !== $.ui.keyCode.TAB) {
                return;
            }

            var tabbables = $(':tabbable', this),
                first = tabbables.filter(':first'),
                last  = tabbables.filter(':last');

            if (event.target === last[0] && !event.shiftKey) {
                first.focus(1);
                return false;
            } else if (event.target === first[0] && event.shiftKey) {
                last.focus(1);
                return false;
            }
        });

keypress.ui-dialog — это событие с пространством имен. Это позволяет разработчикам легче идентифицировать события, например. для включения и удаления. Но с функциональной точки зрения вы можете считать это обычным событием keypress.

person William Niu    schedule 14.08.2011
comment
Итак... keypress.ui-dialog относится только к событиям нажатия клавиш, которые происходят, когда фокус находится в диалоговом окне? - person Vivian River; 14.08.2011
comment
Это событие с пространством имен. Пожалуйста, смотрите обновленный пост. На ваш вопрос, это, как обычно, захватит все события keypress. - person William Niu; 14.08.2011
comment
Почему вы написали .focus(1)? Я всегда просто пишу .focus(). - person Vivian River; 17.08.2011
comment
Я очень четко заявил, что фрагмент из jQuery UI v1.8.5. Итак, я не писал эту функцию; Команда пользовательского интерфейса jQuery сделала это. Числовой аргумент для .focus(1) — это количество мс для задержки вызова, модифицированная версия фокуса в пользовательском интерфейсе jQuery. Я думаю, что причина задержки в 1 мс заключается в том, чтобы переопределить функцию фокуса в следующем блоке кода (видите, вы видите это в исходном коде). - person William Niu; 17.08.2011

Сделать переполнение тела скрытым

$('body').css({'overflow':'hidden'});

демонстрация серого экрана jQuery

person Pir Abdul    schedule 12.08.2011

Я хотел бы принять ответ Уильяма Ниу, но есть недостаток, который мешает ему работать в моем веб-приложении. Если первым или последним элементом в диалоговом окне является переключатель, этот код не будет работать в IE. Браузер перейдет к группе переключателей один раз.

Если выбрана радиокнопка, которую браузер выделяет при переходе пользователя к группе радиокнопок, тогда этот код будет работать. Однако выбранная радиокнопка не является той, которую браузер выделяет при переходе пользователя к группе радиокнопок, тогда фокус будет потерян из диалогового окна.

Вот код, который я написал, который решает эту проблему:

function _bindTabKeyForDialog(dialogId) {
    var tabbable = $('#' + dialogId).find(':tabbable');
    var firstElement = $(tabbable).filter(':first');
    var lastElement = $(tabbable).filter(':last');

    var firstGroup = (firstElement[0].type !== 'radio') ?
        firstElement :
        tabbable.filter("[name='" + firstElement[0].name + "']");
    var lastGroup = (lastElement[0].type !== 'radio') ?
        lastElement :
        tabbable.filter("[name='" + lastElement[0].name + "']");

    $(document).unbind('keydown.' + dialogId);
    $(document).bind('keydown.' + dialogId, function (e) {
        if (e.keyCode == 9) {
            if ($(e.target).is(lastGroup) && !e.shiftKey) {
                firstGroup.first().focus();
                e.preventDefault();
            }
            else if ($(e.target).is(firstGroup) && e.shiftKey) {
                lastGroup.first().focus();
                e.preventDefault();
            }
        }
    });
} // end _bindTabKeyForDialog

Как видите, я заменяю переменные first и last Уильяма на группы элементов. Если первый или последний элемент с вкладками в диалоговом окне является переключателем, он будет включать все переключатели с таким же именем.

В остальном этот код работает так же, как код Уильяма.

person Vivian River    schedule 16.08.2011
comment
Просто чтобы уточнить, я не писал код. Я только извлек соответствующий фрагмент из исходного кода пользовательского интерфейса jQuery, чтобы можно было увидеть, как они это сделали. - person William Niu; 17.08.2011
comment
Поздравляю с найденным решением! Интересно, является ли то, что вы описали в IE, ожидаемым (глючным) поведением (как обычно). Если нет, это может быть ошибка в пользовательском интерфейсе jQuery или jQuery. В этом случае вам следует подумать о том, чтобы отправить им отчет об ошибке. - person William Niu; 17.08.2011