Подтвердить что ты не робот

Есть ли событие DOM, которое срабатывает, когда элемент выбора HTML закрыт?

Я ищу событие DOM, которое я могу прослушивать с помощью JavaScript, когда открывается выбранный элемент (но никаких параметров не изменен) закрывается нажатием элемента select где-нибудь (где угодно) на стр.

Это не событие blur для выбора, так как выбор сохраняет фокус. Точно так же это не событие focus какого-либо другого элемента или документа, или mousedown или click в окне, документе или теле.

Это не событие change для выбора, так как никакая опция в выборе не была изменена.

Меня не интересуют устаревшие Internet Explorers - просто что-то для работы в современных браузерах, совместимых с стандартами. Однако запатентованные хаки могут быть полезны.

Я создал JSFiddle, чтобы продемонстрировать проблему: http://jsfiddle.net/premasagar/FpfnM/

  • Нажмите кнопку выбора на панели "Результат"
  • Нажмите на текст с надписью "ЗДЕСЬ" (или где-нибудь еще) одним щелчком мыши и посмотрите, добавлено ли какое-либо событие в журнал. В последних версиях Chrome или Firefox нет события.

Итак, вопрос: Какой JavaScript можно добавить, чтобы регистрировать событие при нажатии кнопки выбора?

(Я задал аналогичный, но другой вопрос здесь:
JavaScript на iOS: открытие элемента выбора HTML)

4b9b3361

Ответ 1

К сожалению, нет стандартного события для того, чтобы знать, когда окно выбора закрыто или открыто, поэтому ваш код будет довольно волосатым с размещением для разных браузеров. Тем не менее, я думаю, что это можно сделать, и я получил что-то для вас в Firefox, используя событие mouseup:

http://jsfiddle.net/FpfnM/50/

В Firefox (и я предполагаю Chrome) вам нужно будет тщательно отслеживать состояние этого элемента. Когда нажата клавиша escape или событие blur, вам необходимо обновить состояние, чтобы идентифицировать его как закрытое. Я не реализовал это в своей демонстрации, и вы можете увидеть, что произойдет, если вы нажмете escape, а не щелкаете по выбору.

В Safari стало проще, где событие mousedown в select означает открытие выбора, и любое закрытие выбора означает событие click.

Если вы найдете браузер, в котором ни одно из этих событий не срабатывает, вы можете попробовать еще один трюк. Поскольку виджеты форм, такие как select и textarea, часто отображаются операционной системой, а не внутри браузера, возможно, что вы можете взаимодействовать с ними, а некоторые сообщения могут не попасть в обработчик событий браузера. Если бы вы разместили прозрачную текстовую область, закрывающую экран при более низком z-индексе, когда поле выбора открыто, вы можете использовать его для отслеживания этого закрытого клика. Он может улавливать события, которые может отсутствовать элемент DOM браузера.

Update: Chrome видит мульдауны при выборе, когда он открывается, и кнопку мыши в документе, когда нажимается страница с помощью выбора. Здесь версия, которая работает с Chrome:

http://jsfiddle.net/FpfnM/51/

Опять же, вам нужно будет сделать некоторое обнаружение браузера, чтобы справляться с правильным поведением в каждом из них. Один улов с Chrome, в частности, заключается в том, что ни одно событие не запускается, когда вы нажмете второй раз, чтобы закрыть его. Однако вы можете обнаружить щелчок на странице.

Краткое описание:

Chrome/Safari: select.mousedown on open, document.mouseup on close
Firefox: select.click on open, document.mouseup on close
IE8/IE7: select.click on open, document.mouseup on close

Существует множество ошибок для других событий, которые означают закрытие (escape keypress, blur и т.д.), но это минимум для обработки сценария, когда пользователь нажимает кнопку выбора, а затем щелкает области документа.

Надеюсь, это поможет!

Ответ 2

Я получил следующие события, следуя указаниям вашего JSFiddle на письмо:

BODY, mousedown, STRONG
#document, mousedown, STRONG
window, mousedown, STRONG
SELECT, blur, SELECT
BODY, click, STRONG
#document, click, STRONG
window, click, STRONG

Это все события, которые были вызваны, когда я нажал "ЗДЕСЬ" после того, как меню выбора уже было в фокусе и расширено. Это было в последней версии Chrome.

Должно ли какое-либо из них достаточно для ваших целей?

Изменить: если вы хотите, чтобы ваш элемент Select потерял фокус, установите глобальную переменную Javascript "selectFocused" и установите для нее значение False. Установите его значение "Истина", когда ваше меню "Выбор" получает фокус, и установите значение "False" при возникновении любого из указанных выше событий. 'selectFocused' теперь можно использовать в любом месте вашего кода, чтобы определить, имеет ли ваш элемент Select в данный момент фокус, и когда он меняет значения, вы знаете, что ваш элемент Select был выбран или не выбран.

Ответ 3

Мой первый инстинкт - это немного окольный путь, чтобы достичь этого, было бы использовать код, который вы обычно используете для закрытия выпадающего меню (пользовательского), нажимающего снаружи:

function clickInBody(){
 functionToCallOnBlur();
}

function clickInBodyStop(event){
    event.stopPropagation();
}

Затем в теге body вы добавляете onClick="clickInBody()", а в элементе select вы добавляете onClick="clickInBodyStop(event)". Это должно вызывать событие каждый раз, когда вы нажимаете на страницу, но если вы нажмете на тег select, он остановит распространение и не вызовет functionToCallOnBlur()

Ответ 4

precondition: использование jQuery! Это, вероятно, только решает часть вашей проблемы, но если вы хотите, чтобы событие срабатывало при нажатии элемента, вы можете использовать оверлейный div.

Когда пользователь нажимает на поле выбора:

$('#mySelectBox').click(function () {
    var myOverlayDiv = $('<div id="overlayDiv" class="overlayDiv"></div>')
    .click(function () {
        // call your "select lost focus" function here
        // which should include $('#overlayDiv').remove() somewhere!
    })
    .show()
    .appendTo(document.body);
});

Стиль для наложения div:

.overlayDiv {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
opacity:0;
z-index:1000;
}

Вам нужно убедиться, что ваше меню выбора является более высоким Z-индексом, поэтому, когда пользователь нажимает на меню, они получают меню, а не наложение div:)

Ответ 5

Если у вас более 1 раскрывающегося списка:

        $("select").each(function () {
        var initDropdown = $(this);
        initDropdown.data("open", false);
        console.log(this.name + "   closed");

        initDropdown.on("blur", function () {
            var blurDdopdown = $(this);
            blurDdopdown.data("open", false);
            console.log(this.name + "   closed");
        });
    });

    $("select").bind("click", function () {
        var clickedDropdown = $(this);

        if (clickedDropdown.data('open') == false) {
            clickedDropdown.data('open', true);
            console.log(this.name + "   open");
        } else {
            clickedDropdown.data('open', false);
            console.log(this.name + "   closed");
        }
    });