![](/img/trans.png)
[英]Cannot programmatically select radio button if preventDefault() called
[英]Can't check radio button programmatically with preventDefault()
我有一些元素(例如帶有類.label的div),每個元素都有單選按鈕。 當用戶單擊此“標簽”時,我以編程方式將其中的無線電設置為已選中。 但是如果我使用preventDefault()進行點擊事件,如果用戶完全點擊無線電,則無法選擇收音機。
請幫我理解這種奇怪的行為。 我知道解決方案,我知道為什么在父元素上的preventDefault()不允許檢查無線電,但我想明白,為什么無線電上的click事件可以禁止以編程方式設置其狀態 。 你會看到單擊單選按鈕會說收音機已被選中,但事實並非如此。
$(function () { $('.label').on('click', function(e) { var $radio = $(this).find(':radio') console.log('before prevent', `checked=${$radio.prop('checked')}`, `prevented=${e.isDefaultPrevented()}`); e.preventDefault(); if (!$(this).hasClass('checked')) { $('.checked').removeClass('checked'); $(this).addClass('checked'); } $radio.prop('checked', true); console.log('after prevent', `checked=${$radio.prop('checked')}`, `prevented=${e.isDefaultPrevented()}`); setTimeout(function () { console.log('after timeout', `checked=${$radio.prop('checked')}`); }, 500); }); $(':radio').on('click', function (e) { console.log('click', `prevented=${e.isDefaultPrevented()}`); }); });
.label { padding: 10px; margin-bottom: 10px; border: 1px solid #000; } .label.checked { background-color: green; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="label"> Label 1 <input type="radio" name="radio" value="1"> </div> <div class="label"> Label 2 <input type="radio" name="radio" value="2"> </div>
更新 。 我怎么看這種情況:
.label
上觸發 cancelled
標志。 div
將類'.checked'和radio設置為再次檢查,現在以編程方式。 我對嗎?
我如何看待這種情況(受https://stackoverflow.com/a/15767580/11357125啟發):
<input>
<div>
,它被處理。 事件偵聽器調用preventDefault
方法,設置內部cancelled
標志。 <div>
將類'.checked'和radio設置為再次檢查,現在以編程方式 。 在父元素上使用preventDefault()可以防止觸發原始事件,但不會停止傳播。 了解層次結構和事件傳播至關重要。
您的代碼段中包含部分解決方案。 如果您注釋掉該特定行,則代碼可以正常工作,就像您期望的那樣。 但如果你使用
e.stopPropagation();
它也有效。
為了不重復網上已有的信息,我在這里找到了一個非常相似的案例( 為什么在父元素點擊'禁用'一個復選框?上的preventDefault()?這可能有助於你理解更好的事件傳播和冒泡。
您還可以在此處找到更好的解釋( https://medium.freecodecamp.org/a-simplified-explanation-of-event-propagation-in-javascript-f9de7961a06e )。
MDN文檔也很少令人印象深刻( https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault )。
您只需要添加e.stopPropagation()
以再次返回checked
單選按鈕的默認功能
行為是你有radio
是div
的孩子,你click
監聽器是基於父div
,當你preventDefault
,孩子也繼承了預防。
檢查一下
如果按下一個元素上的按鈕並在另一個元素上釋放,則會在包含這兩個元素的最具體的祖先元素上觸發該事件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.