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

Onclick() и onblur()

У меня есть поле ввода, в котором отображается настраиваемое раскрывающееся меню. Я хотел бы использовать следующие функции:

  • Когда пользователь нажимает нигде вне поля ввода, меню следует удалить.
  • Если, более конкретно, пользователь нажимает на div внутри меню, меню должно быть удалено, и специальная обработка должна произойти, на основании которого был нажат div.

Вот моя реализация:

В поле ввода есть событие onblur(), которое удаляет меню (путем установки родительского элемента innerHTML в пустую строку) всякий раз, когда пользователь щелкает за пределами поля ввода. Внутри div также есть onclick() события, которые выполняют специальную обработку.

Проблема в том, что события onclick() никогда не срабатывают при щелчке по меню, потому что поле ввода onblur() срабатывает первым и удаляет меню, включая onclick() s!

Я решил проблему, разделив события div div < > t22 > на onmousedown() и onmouseup() событиями и установив глобальный флаг мыши, который очищается с помощью мыши вверх, подобно тому, что было предложено в этот ответ. Поскольку перед тем, как onblur() срабатывает onmousedown(), флаг будет установлен в onblur(), если было нажато одно из разделов меню, но не было, если в другом месте на экране было. Если щелкнуть меню, я сразу же вернусь из onblur(), не удаляя меню, а затем дождитесь onclick(), и в этот момент я могу безопасно удалить меню.

Есть ли более элегантное решение?

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

<div class="menu" onmousedown="setFlag()" onmouseup="doProcessing()">...</div>
<input id="input" onblur="removeMenu()" ... />

var mouseflag;

function setFlag() {
    mouseflag = true;
}

function removeMenu() {
    if (!mouseflag) {
        document.getElementById('menu').innerHTML = '';
    }
}

function doProcessing(id, name) {
    mouseflag = false;
    ...
}
4b9b3361

Ответ 1

У меня была та же проблема, что и у вас, мой интерфейс разработан именно так, как вы описываете. Я решил проблему, просто заменив onClick для пунктов меню на onMouseDown. Я больше ничего не делал; нет onMouseUp, нет флагов. Это решило проблему, позволив браузеру автоматически переупорядочивать в зависимости от приоритета этих обработчиков событий, без дополнительной работы с моей стороны.

Есть ли причина, по которой это не сработало бы и для вас?

Ответ 2

Заменить на onmousedown с onfocus, Таким образом, это событие будет срабатывать, когда фокус находится внутри текстового поля.

Замените на onmouseup с onblur, Когда вы выберете фокус из текстового поля, будет выполняться onblur.

Я думаю, это то, что вам может понадобиться.

UPDATE

при выполнении вашей функции onfocus → удалить классы, которые будут применяться в onblur, и добавить классы, которые вы хотите выполнить в фокусе

и

когда вы выполняете свою функцию onblur → удалите классы, которые будут применяться в onfocus и добавьте классы, которые вы хотите выполнить onblur

Я не вижу необходимости в переменных флага.

ОБНОВЛЕНИЕ 2:

Вы можете использовать события onmouseout и onmouseover

onmouseover - определяет, когда курсор над ним.

onmouseout - определяет, когда курсор покидает.

Ответ 3

Более элегантное (но скорее менее эффективное) решение:

Вместо того, чтобы использовать ввод onblur для удаления меню, используйте document.onclick, который запускается после onblur.

Однако это также означает, что меню удаляется при нажатии на вход, что является нежелательным поведением. Установите input.onclick с помощью event.stopPropagation(), чтобы избежать распространения кликов на событие щелчка документа.

Ответ 4

onClick не следует заменять на onMouseDown.

Хотя этот подход в некоторой степени работает, это два принципиально разных события, которые имеют разные ожидания в глазах пользователя. Использование onMouseDown вместо onClick нарушит предсказуемость вашего программного обеспечения в этом случае. Таким образом, эти два события не являются взаимозаменяемыми.

Для иллюстрации: при случайном нажатии на кнопку пользователи ожидают, что смогут удерживать нажатой кнопку мыши, перетащить курсор за пределы элемента и отпустить кнопку мыши, что в конечном итоге не приведет к каким-либо действиям. onClick делает это. onMouseDown не позволяет пользователю удерживать мышь нажатой, а вместо этого немедленно запускает действие, без какой-либо помощи для пользователя. onClick - это стандарт, по которому мы ожидаем запуска действий на компьютере.

В этой ситуации вызовите event.preventDefault() для события onMouseDown. По умолчанию onMouseDown вызывает событие размытия по умолчанию и не будет делать это при вызове preventDefault. Тогда у onClick будет шанс позвонить. Событие размытия все равно произойдет, только после onClick.

В конце концов, событие onClick является комбинацией onMouseDown и onMouseUp, если и только если они оба происходят в одном и том же элементе.

Ответ 5

изменить onclick с помощью onfocus

даже если onblur и onclick не очень хорошо ладят друг с другом, но очевидно onfocus и yes onblur. поскольку даже после закрытия меню онфокус по-прежнему действует для элемента, щелкнувшего внутри.

Я сделал, и это сработало.

Ответ 6

Вы можете использовать функцию setInterval внутри вашего обработчика onBlur, например:

<input id="input" onblur="removeMenu()" ... />

function removeMenu() {
    setInterval(function(){
        if (!mouseflag) {
            document.getElementById('menu').innerHTML = '';
        }
    }, 0);
}

функция setInterval удалит вашу функцию onBlur из стека вызовов, добавит, потому что вы установите время на 0, эта функция вызывается сразу после завершения обработчика других событий