Предотвратить событие onclick на кнопке от срабатывания при нажатии Enter в другом окне - PullRequest
0 голосов
/ 09 июня 2018

Мне нужно иметь поле ввода пользователя в #wmd-button-bar редактора SE вместе с кнопкой.Пользователь может ввести некоторые данные в поле ввода, а затем нажать кнопку для обработки этих данных.Я использую usercript для достижения этой цели.Я создал отдельный MVCE для этого, и вот его прямая ссылка 1003 * для Tampermonkey / Greasemonkey.

Чтобы воспроизвести проблему, установите usercript.Перезагрузите эту страницу и нажмите «Изменить».Вы заметите новое пустое поле ввода с кнопкой.Сфокусируйте поле «Редактировать сводку» пустым, оставьте его пустым и нажмите Enter.Вместо того, чтобы отправлять окно ответа, ваша каретка теперь вместо этого сфокусируется на новом пустом поле ввода.

То же самое происходит, если вы нажмете Enter в поле «Заголовок вопроса».

Из сообщений console.log вы заметите, что вместо этого на событии MouseClick произошлокнопка!Это не ожидаемое поведение.На самом деле, как это вообще возможно?Мы просто нажали Enter в окне редактирования сводки и даже не коснулись ни нового пустого ввода, ни его кнопки.Как же тогда регистрировать щелчок мышью?

Как это исправить?

Примечание: Необходим e.preventDefault(); внутри кнопки обработчик onclick.В противном случае, когда пользователь нажимает кнопку для обработки своих входных данных, вместо этого отправляется поле ответа.


Код пользователя :

function createModal(buttonBar){
    var div = document.createElement("div"),
        input = document.createElement("input"),
        btn = document.createElement("button");

    div.id = "box";

    input.type = "text";

    btn.innerHTML = "Button";
    btn.onclick = function(e){
        e.preventDefault();
        console.log("I was called");
        input.focus();
        console.dir(e);
        console.trace();
    };

    div.appendChild(input);
    div.appendChild(btn);

    return div;
}

setInterval(function () {
    var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;

    if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
        cont.classList.add("processed");

        buttonBar = cont.querySelector("div[id^=wmd-button-bar]");

        div = createModal(buttonBar);
        buttonBar.appendChild(div);
    }
}, 500)

Ответы [ 2 ]

0 голосов
/ 21 июня 2018

Стандартное поведение HTML.Все buttons внутри form имеют type="submit".При нажатии enter нажата самая последняя кнопка form, и по умолчанию вызываются их обработчики.Чтобы исправить это, кнопки создаются с помощью type="button".

console.log(document.querySelector("#a").type)
console.log(document.querySelector("#b").type)
console.log(document.querySelector("#c").type)
<form>
    <input type="text">
    <button id="a" onclick="console.log('a')">Submit type</button>
    <button id="b" onclick="console.log('b')" type="button">Button type</button>
    <input id="c" type="submit" value="Input Submit type">
</form>

Вы можете отослать это , чтобы понять поведение <button> и <input type="button">.

Если вы простоустановите флажок в консоли, например, document.querySelector("#box").children[1].type будет отображаться как submit.

Кнопка по умолчанию действует как тип submit, если она не указана явно (либо submit (по умолчанию) / reset/ button).Просто запустите document.querySelector("#box").children[1].type=button.Вы работаете, как ожидалось.

Поведение в кросс-браузерном режиме такое же, как и в Firefox Nightly (версия для разработчиков), Chrome и Safari и работают немного по-другому в IE.

Также вы можете видеть, что щелчок по умолчанию - это console.log(event.detail), равный 0, поскольку он запускается изнутри.При срабатывании левой кнопкой мыши это будет 1. MDN Документы по событию клика

0 голосов
/ 21 июня 2018

я попробовал следующий код в браузере Firefox, и он работает как положено.

function createModal(buttonBar){
    var div = document.createElement("div"),
        input = document.createElement("input"),
        btn = document.createElement("button");

    div.id = "box";

    input.type = "text";
    btn.type = "button";

    btn.innerHTML = "Button";
    btn.onclick = function(e){
        console.log("I was called");
        input.focus();
        console.dir(e);
        console.trace();
    };

    div.appendChild(input);
    div.appendChild(btn);

    return div;
}

setInterval(function () {
    var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;

    if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
        cont.classList.add("processed");

        buttonBar = cont.querySelector("div[id^=wmd-button-bar]");

        div = createModal(buttonBar);
        buttonBar.appendChild(div);
    }
}, 500);

обратите внимание, что я установил btn.type="button";, это гарантирует, что форма не будет отправлена, а также удалена e.preventDefault(); какКнопка никогда не будет отправлять форму сейчас.

имейте в виду, что по умолчанию, если вы не передаете элемент type элементу button, она будет вести себя как кнопка submit.

также происходило событие MouseClick, потому что событие щелчка вызывается на кнопках отправки, присутствующих в форме при отправке формы.поскольку у вас была кнопка без атрибута type, она работала как кнопка отправки.так что событие MouseClick сработало, когда вы нажали Enter (как отправка формы).

вы можете убедиться в этом, добавив обработчик onclick из вашего инструмента разработчика браузера к кнопке Save edits submit инажмите ввод в текстовом поле.

...