我是初学者,正在学习教程并创建了产品颜色定制器。目前,只有一种方法可以取消选中突出显示的区域,那就是在图像外部单击。
如何选择并突出显示一个区域,然后再次单击并选择它以取消选择该特定区域?
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/