簡體   English   中英

復選框 onChange in<legend> 里面殘疾人<fieldset>不使用 React 在 Firefox 中觸發

[英]checkbox onChange in <legend> inside disabled <fieldset> not firing in Firefox with React

以下適用於 Firefox 80.0 和 Chromium 84.0.4147.89。

 const fieldset = document.getElementById("fieldset"); const toggle = document.getElementById("toggle"); toggle.addEventListener("change", () => { if (fieldset.hasAttribute("disabled")) { fieldset.removeAttribute("disabled"); } else { fieldset.setAttribute("disabled", true); } });
 <form action="#"> <fieldset id="fieldset"> <legend> <label>toggle <input id="toggle" type="checkbox" /></label> </legend> <input /> </fieldset> </form>

但是,當我嘗試在 React 中做類似的事情時,它在 Firefox 中不起作用。 一旦字段集被禁用, onChange 事件似乎不會觸發。

 function App() { const [disabled, setDisabled] = React.useState(false); const toggleDisabled = React.useCallback(() => { setDisabled((disabled) => !disabled); }, []); return ( <form action="#"> <fieldset disabled={disabled}> <legend> <label> toggle <input onChange={toggleDisabled} type="checkbox" /> </label> </legend> <input /> </fieldset> </form> ); } ReactDOM.render(<App />, document.getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script> <div id="root"></div>

MDN 字段集文章說:

[禁用 fieldset 元素時] 請注意, <legend>元素內的表單元素不會被禁用。

W3C(示例 B)WHATWG還提到不應禁用<legend>的內容。

所以我相信這兩段代碼應該以相同的方式運行:我應該能夠使用復選框切換disabled屬性。

如何在 Firefox 80.0+ 上的 React 中實現相同的效果?

根據該段落前面的 2 行,瀏覽器似乎預期此行為。

disabled如果設置了這個布爾屬性,所有作為<fieldset>后代的表單控件都被禁用,這意味着它們不可編輯並且不會與 . 他們不會收到任何瀏覽事件,例如鼠標點擊或與焦點相關的事件 默認情況下,瀏覽器將此類控件顯示為灰色。 請注意,元素內的表單元素不會被禁用。 - MDN

Firefox 似乎完全按照它的描述做了它應該做的事情。
這里的一個解決方案是將<input>放在字段集之外,這樣它就不會受到disabled屬性的影響。


編輯

您關於偵聽 DOM 中更高層事件的評論讓我開始思考。 如果您通過將自己的事件偵聽器與良好的 ol' addEventListener結合使用useRefuseEffect鈎子來繞過它如何。 創建對復選框的引用並在第一次渲染后監聽更改事件。 現在事件正在偵聽輸入本身。
這種“解決方法”似乎在 FF 中有效。

 function App() { const [disabled, setDisabled] = React.useState(false); const toggleElement = React.useRef(null) const toggleDisabled = React.useCallback(() => { setDisabled(disabled => !disabled); }, []); React.useEffect(() => { toggleElement.current.addEventListener('change', toggleDisabled); }, []); return ( <form action="#"> <fieldset disabled={disabled}> <legend> <label> toggle <input ref={toggleElement} type="checkbox" /> </label> </legend> <input /> </fieldset> </form> ); } ReactDOM.render(<App />, document.getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script> <div id="root"></div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM