#javascript #html
#javascript #HTML
Вопрос:
window.onload = function(){
var wow = document.getElementById("wow");
wow.onclick = function(){
alert("hi");
}
}
<label id="wow"><input type="checkbox" name="checkbox" value="value">Text</label>
Это мой код, когда я нажимаю на «Текст», он дважды предупреждает hi, но когда я нажимаю на поле, onclick
элемент срабатывает только один раз, почему?
Комментарии:
1. вам нужно предупреждение при загрузке Windows?
2. @Niang нет, когда по тексту щелкают
Ответ №1:
Когда вы нажимаете на ярлык, он запускает обработчик кликов, и вы получаете предупреждение.
Но щелчок по метке также автоматически отправляет событие click в связанный элемент input, поэтому это рассматривается как щелчок по флажку. Затем всплывающее окно события приводит к тому, что событие click запускается для содержащего элемента, который является label, поэтому ваш обработчик запускается снова.
Если вы измените свой HTML на это, вы не получите двойное предупреждение:
<input id="wowcb" type="checkbox" name="checkbox" value="value">
<label id="wow" for="wowcb">Text</label>
Метка теперь связана с флажком с помощью for
атрибута вместо обертывания вокруг него.
Комментарии:
1. Наверное, я никогда не замечал этого, потому что обычно я просто помещал обработчик «click» на
<input>
, а не на ярлык. Это любопытное поведение, и я не уверен, что могу придумать причину, по которой это было бы полезно.2. Вы также можете остановить распространение событий.
3. В идеале вместо этого следовало бы привязать обработчик события изменения. Отлично подходит для доступности.
4. @FelixKling Вы не можете привязать обработчик изменений к метке, AFAIK.
5. @MMiller Да, но для этого вам придется добавить обработчик щелчков в флажок.
Ответ №2:
Если вы намерены реагировать только на щелчки по ярлыку, а не на флажок, вы можете посмотреть на свойство event.target.targettarget. Он ссылается на элемент, который вызвал прослушиватель, так что, если щелчок не был на этом элементе, не выполняйте действие:
window.onload = function(){
var el = document.getElementById('wow');
el.addEventListener('click', function(event) {
if (this === event.target) {
/* click was on label */
alert('click was on label');
} else {
/* click was on checkbox */
event.stopPropagation();
return false;
}
}, false);
}
Если, с другой стороны, вы хотите отвечать только на щелчки по флажку (где щелчок по ярлыку также приводит к щелчку по флажку), тогда сделайте обратное. Ничего не делайте для кликов по метке и пропускайте клики из флажка через:
window.onload = function(){
var el = document.getElementById('foolabel');
el.addEventListener('click', function(event) {
if (this === event.target) {
/* click was on label */
event.stopPropagation();
return false;
} else {
/*
** click is from checkbox, initiated by click on label
** or checkbox
*/
alert('click from checkbox');
}
}, false);
}
Эта версия, похоже, имеет наиболее естественное поведение. Однако изменение разметки таким образом, чтобы метка больше не закрывала флажок, будет означать, что прослушиватель не вызывается.
Ответ №3:
Пузырь событий.
Флажок является дочерним узлом метки. Вы устанавливаете флажок. Всплывающее событие для метки. Затем дважды появляется предупреждение.
Чтобы предупреждение не появлялось дважды при нажатии флажка. Вы можете изменить свою функцию onclick на это:
wow.onclick = function(e){
alert('hi');
stopBubble(e);
}
function stopBubble(e)
{
if (e amp;amp; e.stopPropagation)
e.stopPropagation()
else
window.event.cancelBubble=true
}
Надеюсь, это сработает для вас.
Комментарии:
1. Я не думаю, что это правильный ответ. Обработчик событий для содержащего
<label>
тега должен получать событие с пузырьками только один раз. Браузеры генерируют два события «click», одно с<input>
элементом в качестве целевого, а другое с<label>
в качестве целевого.2. Всплывает два раза. Один из них происходит от щелчка по ярлыку. Другой — щелкните входной пузырь на ярлыке. Я думаю, это может объяснить это.: )
3. Нет, пузырьковый процесс включает только один объект события, который доставляется обработчикам событий в родительских элементах. В этом случае объект события отличается при двух вызовах обработчика.
4. Это не работает: jsfiddle.net/barmar/fMMAz/5 Распространение от метки к флажку не происходит с пузырьками, это что-то очень специфичное для меток.
5. Нет, это не так. Я нажал на «Текст» и получил два предупреждения в Chrome.
Ответ №4:
Тег Label будет связан с тегом input внутри него. Поэтому, когда вы нажимаете на метку, это также запускает событие click для ввода, а затем переходит к самой метке.
Смотрите это:
document.getElementById("winput").addEventListener('click', function(event){
alert('input click');
//stop bubble
event.stopPropagation();
}, false);
Ответ №5:
Снова столкнулся с этой проблемой и решил доказать, что это сделало для меня, надеюсь, это поможет мне вспомнить. Чтобы помочь будущим людям, которым вышеупомянутое может быть недостаточно понятным, вот пример, который я привел.
https://jsfiddle.net/ashes/0bcauenm/
$(".someBigContainer").on("click", "input[type=checkbox]", ()=> {
$output.val("Clicked: checkboxn" $output.val());
});
редактировать: добавлена ссылка с фрагментом кода.
Ответ №6:
Это, вероятно, самый простой ответ. Просто добавьте интервал вокруг вашего текста и остановите распространение события.
window.onload = function(){
var wow = document.getElementById("wow");
wow.onclick = function(){
alert("hi");
}
}
<label id="wow">
<input type="checkbox" name="checkbox" value="value">
<span onclick="event.stopPropagation()">Text</span>
</label>
Или без встроенного JavaScript
window.onload = function(){
var wow = document.getElementById("wow");
wow.onclick = function(){
alert("hi");
}
var span = document.getElementsByTagName("span")[0];
span.onclick = function(event){
event.stopPropagation();
}
}
<label id="wow">
<input type="checkbox" name="checkbox" value="value">
<span>Text</span>
</label>
Комментарии:
1. Ни одно из этих решений не работает на 100% как есть. У вас есть несколько пробелов, которые попадают в <span> которые найдены: перед флажком, перед «Текстом» прямо между флажком и «Текстом», где, если вы нажмете правильно, вы получите двойное предупрежд ение. Кроме того, вы получаете двойное предупреждение, если вы очень точно нажимаете в любом месте на 1 пиксель прямо за пределами границы фл ажка. (Я использую Windows 10, Chrome 98)
Ответ №7:
Для тех, кто использует React и Material UI — я столкнулся с этой проблемой в одной из моих форм. event.preventDefault()
останавливает запуск события, как описано в принятом ответе.
<Button
onClick={(event) => {
event.preventDefault()
this.handleCardClick(planName)
}}
>
<FormControl component="fieldset">
<RadioGroup
row
value={selectedPlan}
>
<FormControlLabel
control={<Radio color="secondary" />}
label={label}
/>
</RadioGroup>
</FormControl>
</Button>
Ответ №8:
Используйте change
для прослушивания событий вместо click