如何通过单击一次取消选中所有复选框?

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

How to uncheck all checkboxes with a single click?

问题

我用JavaScript编写了一个用于使用<kbd>SHIFT</kbd>键选择复选框的功能。现在我想要通过单击来取消选择。

HTML:

<div class="inbox">
      <div class="item">
        <input type="checkbox" />
        <p>This is an inbox layout.</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Check one item</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Hold down your Shift key</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Check a lower item</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Everything in between should also be set to checked</p>
      </div>
      <div class="item">
        <input type="checkbox" />
        <p>Try do it without any libraries</p>
      </div>
    </div>

JavaScript 用于选择复选框:

const checkboxes = document.querySelectorAll(
        '.inbox input[type="checkbox"]'
      );

      let lastChecked;

      function handleCheck(e) {
        // 用于选择复选框
        let inBetween = false;
        // 检查是否按下了Shift键
        // 并检查是否正在勾选它

        if (e.shiftKey && this.checked) {
          // 继续执行我们的操作
          // 遍历每个复选框
          checkboxes.forEach(checkbox => {
            console.log(checkbox);
            if (checkbox === this || checkbox === lastChecked) {
              inBetween = !inBetween;
              console.log('Starting to check them in between!');
            }

            if (inBetween) {
              checkbox.checked = true;
            }
          });
        }

        lastChecked = this;
      }

      checkboxes.forEach(checkbox =>
        checkbox.addEventListener('click', handleCheck)
      );

我希望在使用<kbd>SHIFT</kbd>键选择后,当我单击已选择的复选框时,后面的已选择复选框将会取消选择,只需单击一次。

英文:

I made this in JavaScript for selecting checkboxes using the <kbd>SHIFT</kbd> key. Now I want to deselect it by a single click.

HTML:

&lt;div class=&quot;inbox&quot;&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;This is an inbox layout.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Check one item&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Hold down your Shift key&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Check a lower item&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Everything in between should also be set to checked&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Try do it without any libraries&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;

JavaScript to select the checkbox:

 const checkboxes = document.querySelectorAll(
        &#39;.inbox input[type=&quot;checkbox&quot;]&#39;
      );

      let lastChecked;

      function handleCheck(e) {
        //for selecting the checkboxes
        let inBetween = false;
        // Check if they had the shift key down
        // AND check that they are checking it

        if (e.shiftKey &amp;&amp; this.checked) {
          // go ahead and do what we please
          // loop over every single checkbox
          checkboxes.forEach(checkbox =&gt; {
            console.log(checkbox);
            if (checkbox === this || checkbox === lastChecked) {
              inBetween = !inBetween;
              console.log(&#39;Starting to check them in between!&#39;);
            }

            if (inBetween) {
              checkbox.checked = true;
            }
          });
        }

        lastChecked = this;
      }

      checkboxes.forEach(checkbox =&gt;
        checkbox.addEventListener(&#39;click&#39;, handleCheck)
      );

I want after selecting with <kbd>SHIFT</kbd> key, when I click on a selected checkbox the selected checkboxes which comes after that to be unchecked with a single click.

答案1

得分: 0

你可以通过将复选框放入一个数组中并获取要检查的复选框范围来简化你的逻辑:

// 将所有复选框收集到一个数组中以便更容易处理
const checkboxes = [...document.querySelectorAll('.inbox input[type="checkbox"])];
let lastChecked;

function handleCheck(e) {
  if (e.shiftKey) {
    // 我们应该将范围内的所有复选框都设置为这个值(包括最后选中的)
    const checked = lastChecked?.checked;
    
    // 获取要检查的复选框范围,从lastChecked到this(包括两者)
    const range = [lastChecked, this].map(check => checkboxes.indexOf(check)).sort((a, b) => a - b);
    
    // 获取范围内的复选框并将其选中
    checkboxes.slice(range[0], range[1] + 1).forEach(check => check.checked = checked);
  }
  lastChecked = this;
}

checkboxes.forEach(checkbox =>
  checkbox.addEventListener('click', handleCheck)
);
p {
  display: inline-block;
  margin: 0;
}
<div class="inbox">
  <div class="item">
    <input type="checkbox" />
    <p>This is an inbox layout.</p>
  </div>
  <div class="item">
    <input type="checkbox" />
    <p>Check one item</p>
  </div>
  <div class="item">
    <input type="checkbox" />
    <p>Hold down your Shift key</p>
  </div>
  <div class="item">
    <input type="checkbox" />
    <p>Check a lower item</p>
  </div>
  <div class="item">
    <input type="checkbox" />
    <p>Everything in between should also be set to checked</p>
  </div>
  <div class="item">
    <input type="checkbox" />
    <p>Try do it without any libraries</p>
  </div>
</div>
英文:

You could simplify your logic by putting your checkboxes into an array and getting the range of checkboxes to check:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// collect all the checkboxes into an array for easier handling

const checkboxes = [...document.querySelectorAll(&#39;.inbox input[type=&quot;checkbox&quot;]&#39;)];

let lastChecked;

function handleCheck(e) {
  
  if (e.shiftKey) {

    // we should set all checkboxes in the range with this value (including the last checked)
    const checked = lastChecked?.checked;

    // get the range of checkboxes to check between lastChecked and this (including both)
    const range = [lastChecked, this].map(check =&gt; checkboxes.indexOf(check)).sort((a, b) =&gt; a - b);

    // get checkboxes in the range and check them
    checkboxes.slice(range[0], range[1] + 1).forEach(check =&gt; check.checked = checked);

  }
   

  lastChecked = this;
}

checkboxes.forEach(checkbox =&gt;
  checkbox.addEventListener(&#39;click&#39;, handleCheck)
);

<!-- language: lang-css -->

p{
display:inline-block;
margin:0;
}

<!-- language: lang-html -->

&lt;div class=&quot;inbox&quot;&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;This is an inbox layout.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Check one item&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Hold down your Shift key&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Check a lower item&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Everything in between should also be set to checked&lt;/p&gt;
      &lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;
        &lt;input type=&quot;checkbox&quot; /&gt;
        &lt;p&gt;Try do it without any libraries&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;

<!-- end snippet -->

答案2

得分: 0

你可以将这部分添加到你的 handleCheck 函数中:

else if (e.shiftKey && !this.checked) {
  // 如果按下了 Shift 键并且正在取消选中复选框
  // 遍历每个复选框并取消中间的复选框选中状态
  checkboxes.forEach(checkbox => {
    if (checkbox === this || checkbox === lastChecked) {
      inBetween = !inBetween;
    }

    if (inBetween) {
      checkbox.checked = false;
    }
  });
}
英文:

You can add this to your handleCheck :

else if (e.shiftKey &amp;&amp; !this.checked) {
  // If shift key is down and checkbox is being unchecked
  // loop over every single checkbox and deselect the ones in between
  checkboxes.forEach(checkbox =&gt; {
    if (checkbox === this || checkbox === lastChecked) {
      inBetween = !inBetween;
    }

    if (inBetween) {
      checkbox.checked = false;
    }
  });
}

答案3

得分: 0

似乎您没有检查文档是否准备好。

我只是将您的代码包装在DOMContentLoaded事件监听器中,它可以正常工作。

document.addEventListener("DOMContentLoaded", () => {
  const checkboxes = document.querySelectorAll(
    '.inbox input[type="checkbox"]'
  );

  let lastChecked;

  function handleCheck(e) {
    // 用于选择复选框
    let inBetween = false;
    // 检查是否按下了Shift键
    // 并检查是否正在检查它
    if (e.shiftKey && this.checked) {
      // 继续执行我们想要的操作
      // 循环遍历每个复选框
      checkboxes.forEach(checkbox => {
        console.log(checkbox);
        if (checkbox === this || checkbox === lastChecked) {
          inBetween = !inBetween;
          console.log('Starting to check them in between!');
        }

        if (inBetween) {
          checkbox.checked = true;
        }
      });
    }

    lastChecked = this;
  }

  checkboxes.forEach(checkbox =>
    checkbox.addEventListener('click', handleCheck)
  );
});

如您所见,没有更多要添加的内容。
希望这能帮助到您。

英文:

it seems you do not check the document is ready.

I just wrapped your code into a DOMContentLoaded Eventlistener and it works.

document.addEventListener(&quot;DOMContentLoaded&quot;, () =&gt; {
const checkboxes = document.querySelectorAll(
    &#39;.inbox input[type=&quot;checkbox&quot;]&#39;
  );

  let lastChecked;

  function handleCheck(e) {
    //for selecting the checkboxes
    let inBetween = false;
    // Check if they had the shift key down
    // AND check that they are checking it
    
    if (e.shiftKey &amp;&amp; this.checked) {
      // go ahead and do what we please
      // loop over every single checkbox
      checkboxes.forEach(checkbox =&gt; {
        console.log(checkbox);
        if (checkbox === this || checkbox === lastChecked) {
          inBetween = !inBetween;
          console.log(&#39;Starting to check them in between!&#39;);
        }

        if (inBetween) {
          checkbox.checked = true;
        }
      });
    }

    lastChecked = this;
  }

  checkboxes.forEach(checkbox =&gt;
    checkbox.addEventListener(&#39;click&#39;, handleCheck)
  );
});

As you cann see there isn't more to add.
Hope this will help.

答案4

得分: -1

通过对您的代码进行一些更改,这将实现取消选中和选中的功能。它会停在最后一个已选中(或取消选中)的位置,与您的原始示例相同,我假设这是您想要的行为。

const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');

let lastChecked;

function handleCheck(e) {
    // 用于选择复选框
    let inBetween = false;
    // 检查是否按下了Shift键
    // 并检查是否正在选中它

    if (e.shiftKey/* && this.checked */) { // 忽略当前的选中状态
        // 继续执行我们希望的操作
        // 遍历每个复选框
        checkboxes.forEach((checkbox) => {
            console.log(checkbox);
            if (checkbox === this || checkbox === lastChecked) {
                inBetween = !inBetween;
                console.log("开始选中它们之间的复选框!");
            }

            if (inBetween) {
                checkbox.checked = this.checked; // 处理选中/取消选中
            }
        });
    }

    lastChecked = this;
}

checkboxes.forEach((checkbox) =>
    checkbox.addEventListener("click", handleCheck)
);

注意:上面的代码用于处理复选框的选择和取消选择操作,它允许使用Shift键来一次性选择多个复选框。

英文:

With a couple changes to your code, this should accomplish unchecking as well as checking. It will stop at the lastChecked (or unchecked) as in your original example, I assumed that's the behavior you wanted.

const checkboxes = document.querySelectorAll(&#39;.inbox input[type=&quot;checkbox&quot;]&#39;);

let lastChecked;

function handleCheck(e) {
    //for selecting the checkboxes
    let inBetween = false;
    // Check if they had the shift key down
    // AND check that they are checking it

    if (e.shiftKey/* &amp;&amp; this.checked */) { // ignore current checked state
        // go ahead and do what we please
        // loop over every single checkbox
        checkboxes.forEach((checkbox) =&gt; {
            console.log(checkbox);
            if (checkbox === this || checkbox === lastChecked) {
                inBetween = !inBetween;
                console.log(&quot;Starting to check them in between!&quot;);
            }

            if (inBetween) {
                checkbox.checked = this.checked; // handles both checked/unchecked
            }
        });
    }

    lastChecked = this;
}

checkboxes.forEach((checkbox) =&gt;
    checkbox.addEventListener(&quot;click&quot;, handleCheck)
);

huangapple
  • 本文由 发表于 2023年7月20日 16:05:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727839.html
匿名

发表评论

匿名网友

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

确定