javascript - 如何选择然后取消选择区域?

标签 javascript html css

我是初学者,正在学习教程并创建了产品颜色定制器。目前,只有一种方法可以取消选中突出显示的区域,那就是在图像外部单击。

如何选择并突出显示一个区域,然后再次单击并选择它以取消选择该特定区域?

const overlays = [];
document.querySelectorAll(".product").forEach(function (path) {
  path.onclick = chooseProduct;
});

function chooseProduct(e) {
  overlays.push(e.target);
  overlays.forEach((overlay) => overlay.classList.add("highlight"));
}

var removeHighlight = function (e) {
  var products = document.querySelectorAll(".product");

  if (
    !e.target.classList.contains("product") &&
    !e.target.classList.contains("color")
  ) {
    overlays.length = 0;
    document.querySelectorAll(".product").forEach(function (prod) {
      prod.classList.remove("highlight");
    });
  }
};
document.onclick = removeHighlight;

var el = document.getElementsByClassName("color");
for (var i = 0; i < el.length; i++) {
  el[i].onclick = changeColor;
}

function changeColor(e) {
  // get the hex color
  let hex = e.target.getAttribute("data-hex");
  overlays.forEach((overlay) => (overlay.style.fill = hex));
}
body,
html {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}

#container {
  height: 200px;
  width: 200px;
}

#product-svg {
  position: relative;
  z-index: 2;
  background-size: 100%;
  background-repeat: no-repeat;
  background-position: 50%;
  mix-blend-mode: multiply;
}

path {
  fill: #cccccc;
}

#background-image {
  position: relative;
  z-index: 1;
  width: 85%;
  height: auto;
}

[data-test] {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: start;
  padding-left: 15px;
  padding-right: 15px;
}

[data-test] span.color {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  width: 60px;
  padding-bottom: 9px;
}

[data-test] span.color span {
  height: 23px;
  width: 20px;
  background: var(--color);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  margin-bottom: -6px;
}

[data-test] span.color span:first-child {
  margin-left: 1px;
}

.highlight {
  stroke-width: 10px;
  stroke: #000;
}

.red {
  z-index: 2;
  padding: 100px;
}
<div id="container">
  <svg id="product-svg" viewBox="0 0 744 1074">
    <path id="product-a" class="product" d="M51 207.5L51 348L686 348L686 67L51 67L51 207.5Z" />
    <path id="product-b" class="product" d="M51 544.5L51 685L686 685L686 404L51 404L51 544.5Z" />
    <path id="product-c" class="product" d="M51 883.5L51 1024L686 1024L686 743L51 743L51 883.5Z" />

  </svg>
  <img>
</div>
<div class="text"><span class="product-number"></span></div>
</div>

<div class="mySlides fade">
  <img>
  <div class="text"><span class="product-number"></span></div>
</div>

<div class="mySlides fade">
  <img>
  <div class="text"><span class="product-number"></span></div>
</div>

</div>

</main>

<section class="color-select">

  <div data-test>
    <span class="color red">
      <span class="color-selected" style="--color: #ff0000 " data-hex="#ff0000"></span>
      <span class="color-selected" style="--color: #660000 " data-hex="#660000"></span>
      <span class="color-selected" style="--color: #990000 " data-hex="#990000"></span>
      <span class="color-selected" style="--color: #cc0000 " data-hex="#cc0000"></span>
      <span class="color-selected" style="--color: #ff6666 " data-hex="#ff6666"></span>
      <span class="color-selected" style="--color: #ff9999 " data-hex="#ff9999"></span>
      <span class="color-selected" style="--color: #ffcccc " data-hex="#ffcccc"></span>
    </span>

  </div>
</section>

最佳答案

我对您的 chooseProduct 函数进行了以下调整以达到预期的效果——显然您可能想要重组、重命名并适本地抽象此功能,但它满足您的要求:

function chooseProduct(e) {
  // iterate over the overlays...
  for (let i = 0; i < overlays.length; i += 1) {
    let currentOverlay = overlays[i];
    // and if the item you just clicked is already in overlays...
    if (currentOverlay.isSameNode(e.target)) {
      // remove it from overlays...
      overlays.splice(i, 1);
      // remove its highlight class...
      e.target.classList.remove('highlight')
      // and exit the function completely-- we don't want to re-add it
      return;
    }
  }
  // else;

  overlays.push(e.target);
  overlays.forEach((overlay) => overlay.classList.add("highlight"));

}

您可以在下面的代码片段中看到它的工作情况:

const overlays = [];
document.querySelectorAll(".product").forEach(function(path) {
  path.onclick = chooseProduct;
});

function chooseProduct(e) {
  // iterate over the overlays...
  for (let i = 0; i < overlays.length; i += 1) {
    let currentOverlay = overlays[i];
    // and if the item you just clicked is already in overlays...
    if (currentOverlay.isSameNode(e.target)) {
      // remove it from overlays...
      overlays.splice(i, 1);
      // remove its highlight class...
      e.target.classList.remove('highlight')
      // and exit the function completely-- we don't want to re-add it
      return;
    }
  }
  // else;

  overlays.push(e.target);
  overlays.forEach((overlay) => overlay.classList.add("highlight"));

}

var removeHighlight = function(e) {
  var products = document.querySelectorAll(".product");

  if (!e.target.classList.contains("product") &&
    !e.target.classList.contains("color")
  ) {
    overlays.length = 0;
    document.querySelectorAll(".product").forEach(function(prod) {
      prod.classList.remove("highlight");
    });
  }
};
document.onclick = removeHighlight;

var el = document.getElementsByClassName("color");
for (var i = 0; i < el.length; i++) {
  el[i].onclick = changeColor;
}

function changeColor(e) {
  // get the hex color
  let hex = e.target.getAttribute("data-hex");
  overlays.forEach((overlay) => (overlay.style.fill = hex));
}
body,
html {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}

#container {
  height: 200px;
  width: 200px;
}

#product-svg {
  position: relative;
  z-index: 2;
  background-size: 100%;
  background-repeat: no-repeat;
  background-position: 50%;
  mix-blend-mode: multiply;
}

path {
  fill: #cccccc;
}

#background-image {
  position: relative;
  z-index: 1;
  width: 85%;
  height: auto;
}

[data-test] {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: start;
  padding-left: 15px;
  padding-right: 15px;
}

[data-test] span.color {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  width: 60px;
  padding-bottom: 9px;
}

[data-test] span.color span {
  height: 23px;
  width: 20px;
  background: var(--color);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  margin-bottom: -6px;
}

[data-test] span.color span:first-child {
  margin-left: 1px;
}

.highlight {
  stroke-width: 10px;
  stroke: #000;
}

.red {
  z-index: 2;
  padding: 100px;
}
<div id="container">
  <svg id="product-svg" viewBox="0 0 744 1074">
    <path id="product-a" class="product" d="M51 207.5L51 348L686 348L686 67L51 67L51 207.5Z" />
    <path id="product-b" class="product" d="M51 544.5L51 685L686 685L686 404L51 404L51 544.5Z" />
    <path id="product-c" class="product" d="M51 883.5L51 1024L686 1024L686 743L51 743L51 883.5Z" />

  </svg>
  <img>
</div>
<div class="text"><span class="product-number"></span></div>
</div>

<div class="mySlides fade">
  <img>
  <div class="text"><span class="product-number"></span></div>
</div>

<div class="mySlides fade">
  <img>
  <div class="text"><span class="product-number"></span></div>
</div>

</div>

</main>

<section class="color-select">

  <div data-test>
    <span class="color red">
      <span class="color-selected" style="--color: #ff0000 " data-hex="#ff0000"></span>
    <span class="color-selected" style="--color: #660000 " data-hex="#660000"></span>
    <span class="color-selected" style="--color: #990000 " data-hex="#990000"></span>
    <span class="color-selected" style="--color: #cc0000 " data-hex="#cc0000"></span>
    <span class="color-selected" style="--color: #ff6666 " data-hex="#ff6666"></span>
    <span class="color-selected" style="--color: #ff9999 " data-hex="#ff9999"></span>
    <span class="color-selected" style="--color: #ffcccc " data-hex="#ffcccc"></span>
    </span>

  </div>
</section>

关于javascript - 如何选择然后取消选择区域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68416739/

相关文章:

javascript - 将索引器传递到回调中的问题

javascript - 获取用 PHP 和 javascript 完成游戏的成本时间

javascript - 为什么js中forEach不断递增?但在控制台看起来很完美。

javascript - 如何动态地将相同大小和位置的图像放置在另一个 div 上?

html - 让 Div 覆盖整个页面(不仅仅是视口(viewport))?

html - Bootstrap 卡不维护行列格式

javascript - 屏幕键盘上的 iPad webApps

javascript - y 轴静态绘图线的工具提示

html - 如何在所有换行符上使用相同的填充将文本放在 SVG 图标旁边?

html - 内联显示的位置图像