我有4个SVG圈子,我想在悬停和点击时切换其样式。我一次只希望一个圆圈具有样式,即单击一个圆圈时将样式从一个圆圈中删除。 悬停可使用CSS进行,但我的JavaScript不太正确。
当单击另一个圆时,它将从一个圆中删除样式,但不允许您从活动目标圆中切换样式类。另外,如果单击了SVG圈子之外的任何内容,如何从圈子中删除样式?
var circles = document.querySelectorAll('.svgcircle')
circles = Array.prototype.slice.call(circles);
for (i = 0; i < circles.length; i++) {
(function(index) {
circles[index].addEventListener("click", function() {
var targetcircle = event.target;
for (var j = 0; j < circles.length; j++) {
circles[j].classList.remove("circleTarget");
}
targetcircle.classList.toggle("circleTarget");
})
})(i);
}
html,
body {
height: 100%;
width: 100%;
overflow: hidden;
}
svg {
position: absolute;
top: 35%;
left: 50%;
margin-left: -200px;
padding: 10px;
}
svg circle {
fill: #B5EF8A;
cursor: pointer;
stroke: #56CBF9;
stroke-width: 2px;
}
svg circle:hover {
fill: #fff;
stroke: #56CBF9;
}
.circleTarget {
fill: #fff;
stroke: #56CBF9;
}
<svg height="100" width="400" id="svg">
<circle class="svgcircle" cx="50" cy="50" r="40" />
<circle class="svgcircle" cx="150" cy="50" r="40" />
<circle class="svgcircle" cx="250" cy="50" r="40" />
<circle class="svgcircle" cx="350" cy="50" r="40" />
</svg>
非常感谢。
答案 0 :(得分:2)
您的代码正在清除所有圈子中类的使用,然后在被单击的圈子中切换该类,但这将始终导致被单击的圈子变为活动状态(因为您刚刚清除了所有类)。 您需要检查被点击的圈子是否已经处于活动状态并以此为依据。
通过使用事件委托,您可以使代码更简单。您不必在每个圈子上都设置事件处理程序,并且可以轻松地检查不在圈子上的点击。这称为event delegation。
此外,由于您是将圈子转换为数组,因此请使用Array.forEach()
方法进行循环,这比管理循环索引要简单得多。
查看内联评论:
var circles = Array.prototype.slice.call(document.querySelectorAll('.svgcircle'));
// Setting the event listener on the document, kills two birds
// with one stone. It removes the need to set click event handlers
// on each circle and it allows for easy checking to see if you
// clicked on anything other than a circle.
document.addEventListener("click", function(evt){
// Check to see if the clicked element was one of the circles:
if(evt.target.classList.contains("svgcircle")){
// It was, so capture whether the clicked circle is active already
let active = evt.target.classList.contains("circleTarget");
removeClass(); // Reset the class usage on all the circles
// If the clicked circle was active, deactivate it.
// Otherwise, activate it:
if(active){
evt.target.classList.remove("circleTarget");
} else {
evt.target.classList.add("circleTarget");
}
} else {
// It wasn't, so clear all the styling from all the circles
removeClass();
}
});
function removeClass(){
// Loop over all the circles and remove the target class
circles.forEach(function(cir){
cir.classList.remove("circleTarget");
});
}
html,
body {
height: 100%;
width: 100%;
overflow: hidden;
}
svg {
position: absolute;
top: 35%;
left: 50%;
margin-left: -200px;
padding: 10px;
}
svg circle {
fill: #B5EF8A;
cursor: pointer;
stroke: #56CBF9;
stroke-width: 2px;
}
svg circle:hover {
fill: #fff;
stroke: #56CBF9;
}
.circleTarget {
fill: #fff;
stroke: #56CBF9;
}
<svg height="100" width="400" id="svg">
<circle class="svgcircle" cx="50" cy="50" r="40" />
<circle class="svgcircle" cx="150" cy="50" r="40" />
<circle class="svgcircle" cx="250" cy="50" r="40" />
<circle class="svgcircle" cx="350" cy="50" r="40" />
</svg>
答案 1 :(得分:1)
这将按照您的预期执行:
let circles = Array.from(document.querySelectorAll('.svgcircle'));
circles.forEach(circle => {
circle.addEventListener("click", ({target}) => {
circles.forEach(c => target !== c && c.classList.remove("circleTarget"));
target.classList.toggle("circleTarget");
})
});
// Remove class if anything else is clicked
document.body.addEventListener('click', ({target}) =>
!Array.from(target.classList).includes('svgcircle')
&& circles.forEach(c => c.classList.remove("circleTarget")));
html,
body {
height: 100%;
width: 100%;
overflow: hidden;
}
svg {
position: absolute;
top: 35%;
left: 50%;
margin-left: -200px;
padding: 10px;
}
svg circle {
fill: #B5EF8A;
cursor: pointer;
stroke: #56CBF9;
stroke-width: 2px;
}
svg circle:hover {
fill: #fff;
stroke: #56CBF9;
}
.circleTarget {
fill: #fff;
stroke: #56CBF9;
}
<svg height="100" width="400" id="svg">
<circle class="svgcircle" cx="50" cy="50" r="40" />
<circle class="svgcircle" cx="150" cy="50" r="40" />
<circle class="svgcircle" cx="250" cy="50" r="40" />
<circle class="svgcircle" cx="350" cy="50" r="40" />
</svg>
希望这会有所帮助,