如何修复在Firefox中无法选中但在Chrome中正常工作的React/JSX复选框?

huangapple go评论69阅读模式
英文:

How may I fix a React/JSX checkbox that is not checking in Firefox, but works as intended in Chrome?

问题

我正在React中构建一个ToDo列表。我有一个包含ul的组件,其中li项是复选框。复选框在Chrome中按预期工作,但在Mozilla中点击时不会选中。我该如何更正此问题,以使复选框与所有浏览器兼容?谢谢您的任何帮助。

GitHub链接

App.jsx 代码

import "./styles.css";

export default function App() {
  return (
    <>
      <form className="new-item-form">
        <div className="form-row">
          <label htmlFor="item">New Item</label>
          <input type="text" id="item" />
        </div>
        <button className="button">Add</button>
      </form>
      <h1 className="header">Todo List</h1>
      <ul className="list">
        <li>
          <label>
            <input type="checkbox" />
            Item 1
          </label>
          <button className="btn btn-danger">Delete</button>
        </li>
        <li>
          <label>
            <input type="checkbox" />
            Item 2
          </label>
          <button className="btn btn-danger">Delete</button>
        </li>
      </ul>
    </>
  );
}

styles.css 代码

* {
  font-family: Arial, Helvetica, sans-serif;
  box-sizing: border-box;
}

body {
  background: #333;
  color: hsl(200, 100%, 90%);
  max-width: 400px;
  padding: 1rem;
  margin: 0 auto;
}

.new-item-form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.form-row {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.btn {
  background: hsl(200, 100%, 50%, 0.1);
  border: 1px solid hsl(200, 100%, 50%);
  color: hsl(200, 100%, 50%);
  padding: 0.25em 0.5em;
  border-radius: 0.25em;
  cursor: pointer;
  outline: none;
}

.btn:hover,
.btn:focus-visible {
  background: hsl(200, 100%, 50%, 0.2);
}

.btn.btn-danger {
  background: hsl(0, 100%, 40%, 0.1);
  border: 1px solid hsl(0, 100%, 40%);
  color: hsl(0, 100%, 40%);
}

.btn.btn-danger:hover,
.btn.btn-danger:focus-visible {
  background: hsl(0, 100%, 40%, 0.2);
}

.new-item-form input {
  outline: none;
  border: 1px solid hsl(200, 100%, 40%);
  background: hsl(200, 100%, 30%);
  border-radius: 0.25em;
  padding: 0.25em 0.5em;
  color: hsl(200, 100%, 90%);
}

.new-item-form input:focus {
  border: 1px solid hsl(200, 100%, 70%);
}

.header {
  font-size: 1.5rem;
  margin-top: 1.5rem;
  margin-bottom: 0.5rem;
}

.list {
  margin: 0;
  padding: 0;
  margin-left: 1rem;
  list-style: none;
}

.list li:has(input:checked) label {
  color: hsl(200, 20%, 40%);
}

.list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.list li {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.list li label {
  display: flex;
  gap: 0.25rem;
  cursor: pointer;
  align-items: center;
}

.list li:has(input:focus-visible) label {
  outline: 1px solid hsl(200, 100%, 50%);
}

.list li input {
  outline: none;
  width: 0;
  height: 0;
  appearance: none;
  pointer-events: none;
  position: absolute;
}

.list li label::before {
  content: "";
  display: block;
  width: 0.9rem;
  height: 0.9rem;
  background: hsl(200, 100%, 90%);
  border-radius: 0.25em;
  display: flex;
  justify-content: center;
  align-items: center;
}

.list li label:hover::before {
  background: hsl(200, 100%, 80%);
}

.list li:has(input:checked) label::before {
  content: "✔";
  background: hsl(200, 100%, 40%);
  color: hsl(200, 100%, 90%);
  font-size: 0.75rem;
  font-weight: bold;
}

.list li:has(input:checked) label:hover::before {
  background: hsl(200, 100%, 30%);
}

我尝试在调试器中检查,但没有出现错误消息。我最初通过Mozilla的本地主机加载页面时,复选框不起作用。然后,作为故障排除的一部分,我在Chrome中加载了页面,复选框按预期工作。

英文:

I am building a ToDo list in React. I have a component that contains a ul with the li items being check boxes. The check boxes work as intended in Chrome, but do not check when clicked in Mozilla. How may I correct this, so the checkboxes are compatible with all browsers? Thank you for any assistance.

GitHub Link

App.jsx code

import &quot;./styles.css&quot;;
export default function App() {
return (
&lt;&gt;
&lt;form className=&quot;new-item-form&quot;&gt;
&lt;div className=&quot;form-row&quot;&gt;
&lt;label htmlFor=&quot;item&quot;&gt;New Item&lt;/label&gt;
&lt;input type=&quot;text&quot; id=&quot;item&quot; /&gt;
&lt;/div&gt;
&lt;button className=&quot;button&quot;&gt;Add&lt;/button&gt;
&lt;/form&gt;
&lt;h1 className=&quot;header&quot;&gt;Todo List&lt;/h1&gt;
&lt;ul className=&quot;list&quot;&gt;
&lt;li&gt;
&lt;label&gt;
&lt;input type=&quot;checkbox&quot; /&gt;
Item 1
&lt;/label&gt;
&lt;button className=&quot;btn btn-danger&quot;&gt;Delete&lt;/button&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;label&gt;
&lt;input type=&quot;checkbox&quot; /&gt;
Item 2
&lt;/label&gt;
&lt;button className=&quot;btn btn-danger&quot;&gt;Delete&lt;/button&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/&gt;
);
}

styles.css code

* {
font-family: Arial, Helvetica, sans-serif;
box-sizing: border-box;
}
body {
background: #333;
color: hsl(200, 100%, 90%);
max-width: 400px;
padding: 1rem;
margin: 0 auto;
}
.new-item-form {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.form-row {
display: flex;
flex-direction: column;
gap: 0.1rem;
}
.btn {
background: hsl(200, 100%, 50%, 0.1);
border: 1px solid hsl(200, 100%, 50%);
color: hsl(200, 100%, 50%);
padding: 0.25em 0.5em;
border-radius: 0.25em;
cursor: pointer;
outline: none;
}
.btn:hover,
.btn:focus-visible {
background: hsl(200, 100%, 50%, 0.2);
}
.btn.btn-danger {
background: hsl(0, 100%, 40%, 0.1);
border: 1px solid hsl(0, 100%, 40%);
color: hsl(0, 100%, 40%);
}
.btn.btn-danger:hover,
.btn.btn-danger:focus-visible {
background: hsl(0, 100%, 40%, 0.2);
}
.new-item-form input {
outline: none;
border: 1px solid hsl(200, 100%, 40%);
background: hsl(200, 100%, 30%);
border-radius: 0.25em;
padding: 0.25em 0.5em;
color: hsl(200, 100%, 90%);
}
.new-item-form input:focus {
border: 1px solid hsl(200, 100%, 70%);
}
.header {
font-size: 1.5rem;
margin-top: 1.5rem;
margin-bottom: 0.5rem;
}
.list {
margin: 0;
padding: 0;
margin-left: 1rem;
list-style: none;
}
.list li:has(input:checked) label {
color: hsl(200, 20%, 40%);
}
.list {
display: flex;
flex-direction: column;
gap: 0.3rem;
}
.list li {
display: flex;
gap: 0.5rem;
align-items: center;
}
.list li label {
display: flex;
gap: 0.25rem;
cursor: pointer;
align-items: center;
}
.list li:has(input:focus-visible) label {
outline: 1px solid hsl(200, 100%, 50%);
}
.list li input {
outline: none;
width: 0;
height: 0;
appearance: none;
pointer-events: none;
position: absolute;
}
.list li label::before {
content: &quot;&quot;;
display: block;
width: 0.9rem;
height: 0.9rem;
background: hsl(200, 100%, 90%);
border-radius: 0.25em;
display: flex;
justify-content: center;
align-items: center;
}
.list li label:hover::before {
background: hsl(200, 100%, 80%);
}
.list li:has(input:checked) label::before {
content: &quot;✔&quot;;
background: hsl(200, 100%, 40%);
color: hsl(200, 100%, 90%);
font-size: 0.75rem;
font-weight: bold;
}
.list li:has(input:checked) label:hover::before {
background: hsl(200, 100%, 30%);
}

I tried inspecting in the debugger, but no error messages occurred. I originally loaded the page via a local host in Mozilla and the checkboxes did not work. Then I loaded the page in Chrome as part of troubleshooting, and the boxes worked as intended.

答案1

得分: 1

Firefox目前不支持:has伪类。

https://caniuse.com/css-has

我相当确定你可以使用兄弟选择器(+~)来重写你的CSS。

英文:

Firefox doesn't support :has pseudo-class yet.

https://caniuse.com/css-has

I'm pretty sure you can rewrite your css using sibling selector (+ or ~).

答案2

得分: 0

问题出在你的 CSS 代码中。有一些不必要的样式被应用,导致复选框样式出现问题,你可以移除这些样式以确保复选框显示正确。这是更新后的版本。

/* 这里是更新后的 CSS 代码 */
* {
  font-family: Arial, Helvetica, sans-serif;
  box-sizing: border-box;
}

body {
  background: #333;
  color: hsl(200, 100%, 90%);
  max-width: 400px;
  padding: 1rem;
  margin: 0 auto;
}

.new-item-form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.form-row {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.btn {
  background: hsl(200, 100%, 50%, 0.1);
  border: 1px solid hsl(200, 100%, 50%);
  color: hsl(200, 100%, 50%);
  padding: 0.25em 0.5em;
  border-radius: 0.25em;
  cursor: pointer;
  outline: none;
}

.btn:hover,
.btn:focus-visible {
  background: hsl(200, 100%, 50%, 0.2);
}

.btn.btn-danger {
  background: hsl(0, 100%, 40%, 0.1);
  border: 1px solid hsl(0, 100%, 40%);
  color: hsl(0, 100%, 40%);
}

.btn.btn-danger:hover,
.btn.btn-danger:focus-visible {
  background: hsl(0, 100%, 40%, 0.2);
}

.new-item-form input {
  outline: none;
  border: 1px solid hsl(200, 100%, 40%);
  background: hsl(200, 100%, 30%);
  border-radius: 0.25em;
  padding: 0.25em 0.5em;
  color: hsl(200, 100%, 90%);
}

.new-item-form input:focus {
  border: 1px solid hsl(200, 100%, 70%);
}

.header {
  font-size: 1.5rem;
  margin-top: 1.5rem;
  margin-bottom: 0.5rem;
}

.list {
  margin: 0;
  padding: 0;
  margin-left: 1rem;
  list-style: none;
}

.list li:has(input:checked) label {
  color: hsl(200, 20%, 40%);
}

.list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.list li {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.list li label {
  display: flex;
  gap: 0.25rem;
  cursor: pointer;
  align-items: center;
}

.list li:has(input:focus-visible) label {
  outline: 1px solid hsl(200, 100%, 50%);
}

.list li input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.list li input[type="checkbox"] + label {
  position: relative;
  padding-left: 2.5em; /* 根据需要调整 */
  cursor: pointer;
}

.list li input[type="checkbox"] + label::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 0.95em; /* 根据需要调整 */
  height: 0.95em; /* 根据需要调整 */
  border: 2px solid hsl(200, 100%, 40%);
  border-radius: 0.25em;
  background-color: hsl(200, 100%, 30%);
  display: flex; /* 添加 */
  justify-content: center; /* 添加 */
  align-items: center; /* 添加 */
}

.list li input[type="checkbox"]:checked + label::after {
  content: "\2713";
  position: absolute;
  left: 0.35em; /* 根据需要调整 */
  top: 0.15em; /* 根据需要调整 */
  color: hsl(200, 100%, 90%);
  font-size: 0.75rem;
  font-weight: bold;
}

在 App.jsx 文件中,我注意到了一些问题。你需要为 input 标签添加 id 属性,并为 label 添加 htmlFor 属性,以便 React 能够有效处理 UI 更改。愉快的编码!

/* 这里是更新后的 App.jsx 代码 */
import "./styles.css";
import { useState } from "react";

const itemArray = [
  { id: 1, text: "Item 1", checked: false },
  { id: 2, text: "Item 2", checked: false },
  { id: 3, text: "Item 3", checked: false },
  { id: 4, text: "Item 4", checked: false },
  { id: 5, text: "Item 5", checked: false },
];

const App = () => {
  const [items, setItems] = useState(itemArray);

  const handleCheckboxChange = (itemId) => {
    setItems((prevItems) =>
      prevItems.map((item) =>
        item.id === itemId ? { ...item, checked: !item.checked } : item
      )
    );
  };

  return (
    <>
      <form className="new-item-form">
        <div className="form-row">
          <label htmlFor="item">New Item</label>
          <input type="text" id="item" />
        </div>
        <button className="button">Add</button>
      </form>
      <h1 className="header">Todo List</h1>
      <ul className="list">
        {items.map(({ id, text, checked }) => (
          <li key={id}>
            <>
              <input
                type="checkbox"
                id={`checkbox-${id}`}
                name={`checkbox-${id}`}
                checked={checked}
                onChange={() => handleCheckboxChange(id)}
              />
              <label htmlFor={`checkbox-${id}`}>{text}</label>
            </>
            <button className="btn btn-danger">Delete</button>
          </li>
        ))}
      </ul>
    </>
  );
};

export default App;

希望这能帮助你解决问题!

英文:

The problem was in your css code. There were unnecessary styles were applied and causing issues with the checkbox styling, you can remove those styles to ensure proper checkbox appearance. This is the updated version.

* {
  font-family: Arial, Helvetica, sans-serif;
  box-sizing: border-box;
}

body {
  background: #333;
  color: hsl(200, 100%, 90%);
  max-width: 400px;
  padding: 1rem;
  margin: 0 auto;
}

.new-item-form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.form-row {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.btn {
  background: hsl(200, 100%, 50%, 0.1);
  border: 1px solid hsl(200, 100%, 50%);
  color: hsl(200, 100%, 50%);
  padding: 0.25em 0.5em;
  border-radius: 0.25em;
  cursor: pointer;
  outline: none;
}

.btn:hover,
.btn:focus-visible {
  background: hsl(200, 100%, 50%, 0.2);
}

.btn.btn-danger {
  background: hsl(0, 100%, 40%, 0.1);
  border: 1px solid hsl(0, 100%, 40%);
  color: hsl(0, 100%, 40%);
}

.btn.btn-danger:hover,
.btn.btn-danger:focus-visible {
  background: hsl(0, 100%, 40%, 0.2);
}

.new-item-form input {
  outline: none;
  border: 1px solid hsl(200, 100%, 40%);
  background: hsl(200, 100%, 30%);
  border-radius: 0.25em;
  padding: 0.25em 0.5em;
  color: hsl(200, 100%, 90%);
}

.new-item-form input:focus {
  border: 1px solid hsl(200, 100%, 70%);
}

.header {
  font-size: 1.5rem;
  margin-top: 1.5rem;
  margin-bottom: 0.5rem;
}

.list {
  margin: 0;
  padding: 0;
  margin-left: 1rem;
  list-style: none;
}

.list li:has(input:checked) label {
  color: hsl(200, 20%, 40%);
}

.list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}


.list li {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.list li label {
  display: flex;
  gap: 0.25rem;
  cursor: pointer;
  align-items: center;
}

.list li:has(input:focus-visible) label {
  outline: 1px solid hsl(200, 100%, 50%);
}

.list li input[type=&quot;checkbox&quot;] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.list li input[type=&quot;checkbox&quot;] + label {
  position: relative;
  padding-left: 2.5em; /* Adjust as needed */
  cursor: pointer;
}

.list li input[type=&quot;checkbox&quot;] + label::before {
  content: &quot;&quot;;
  position: absolute;
  left: 0;
  top: 0;
  width: 0.95em; /* Adjust as needed */
  height: 0.95em; /* Adjust as needed */
  border: 2px solid hsl(200, 100%, 40%);
  border-radius: 0.25em;
  background-color: hsl(200, 100%, 30%);
  display: flex; /* Added */
  justify-content: center; /* Added */
  align-items: center; /* Added */
}

.list li input[type=&quot;checkbox&quot;]:checked + label::after {
  content: &quot;\2713&quot;;
  position: absolute;
  left: 0.35em; /* Adjust as needed */
  top: 0.15em; /* Adjust as needed */
  color: hsl(200, 100%, 90%);
  font-size: 0.75rem;
  font-weight: bold;
}

In App.jsx file i noticed something. You have to add id attribute to input tag and htmlFor attribute to label so React can deal with UI changes efficiently. Happy coding.

The updated version

import &quot;./styles.css&quot;;
import { useState } from &quot;react&quot;;


const itemArray = [
  { id: 1, text: &quot;Item 1&quot;, checked: false },
  { id: 2, text: &quot;Item 2&quot;, checked: false },
  { id: 3, text: &quot;Item 3&quot;, checked: false },
  { id: 4, text: &quot;Item 4&quot;, checked: false },
  { id: 5, text: &quot;Item 5&quot;, checked: false },
];

const App = () =&gt; {
  const [items, setItems] = useState(itemArray);

  const handleCheckboxChange = (itemId) =&gt; {
    setItems((prevItems) =&gt;
      prevItems.map((item) =&gt;
        item.id === itemId ? { ...item, checked: !item.checked } : item
      )
    );
  };

  return (
    &lt;&gt;
    &lt;form className=&quot;new-item-form&quot;&gt;
      &lt;div className=&quot;form-row&quot;&gt;
        &lt;label htmlFor=&quot;item&quot;&gt;New Item&lt;/label&gt;
        &lt;input type=&quot;text&quot; id=&quot;item&quot; /&gt;
      &lt;/div&gt;
      &lt;button className=&quot;button&quot;&gt;Add&lt;/button&gt;
    &lt;/form&gt;
    &lt;h1 className=&quot;header&quot;&gt;Todo List&lt;/h1&gt;
    &lt;ul className=&quot;list&quot;&gt;
      {items.map(({id, text,checked}) =&gt; (
        &lt;li key={id}&gt;
          &lt;&gt;
            &lt;input
              type=&quot;checkbox&quot;
              id={`checkbox-${id}`}
              name={`checkbox-${id}`}
              checked={checked}
              onChange={() =&gt; handleCheckboxChange(id)}
            /&gt;
            &lt;label htmlFor={`checkbox-${id}`}&gt;{text}&lt;/label&gt;
          &lt;/&gt;
          &lt;button className=&quot;btn btn-danger&quot;&gt;Delete&lt;/button&gt;
        &lt;/li&gt;
      ))}
    &lt;/ul&gt;
  &lt;/&gt;
  );
};

export default App;

huangapple
  • 本文由 发表于 2023年7月7日 02:30:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76631632.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定