将点击突出显示 (CSS class) 复制到多个 SVG 中的相应元素
duplicate click-highlighting (CSS class) to corresponding element across multiple SVGs
我有两个具有相同元素的 SVG。当我单击 SVG1 上的一个元素时,它会通过切换 CSS class 来突出显示。我希望 SGV2 上的相同元素自动突出显示(注意:稍后,我希望能够通过单击 SVG2 来更改 SVG2 上突出显示的内容)。
我已经尝试进行转换 table 所以当我使用 getElementById 捕获 SVG1 点击时,该 ID 被转换为 SVG2 上的相应 ID,然后应用 CSS class,但这不起作用。关于如何执行此操作有什么建议吗?
这是一个 JSfiddle - https://jsfiddle.net/scottmclaughlin/gynzou0t/21/
// changes colour of the clicked element
function highlighter () {
var ellipses = document.getElementById(this.id);
ellipses.classList.toggle("keyHighlight");
// also duplicate highlight on second svg
let duplicateEllipses = (ellipses) => translateTable[ellipses];
duplicateEllipses.classList.toggle("keyHighlight1");
}
不相关,SVG 应该并排放置,但 column/row CSS 出于某种原因不正确。
ellipses
是一个元素而不是 id,你的 duplicateEllipses
用法很奇怪,它被定义为一个函数,但用作一个元素。我认为你应该做的逻辑方式是这样的:
let duplicateEllipses = document.getElementById(translateTable[this.id]);
duplicateEllipses.classList.toggle("keyHighlight1");
不是更简洁的方法,但您可以尝试:
let ellipses = document.querySelectorAll('.ellipsoid')
ellipses.forEach(e => {
e.addEventListener('click', function() {
e.classList.toggle("keyHighlight")
if (e.id.slice(-2) !== '-1') {
let e1 = document.querySelector(`#${e.id}-1`)
if (e1.classList.contains('keyHighlight') && e.classList.contains('keyHighlight')) {
e1.classList.add("keyHighlight")
} else if (!e1.classList.contains('keyHighlight') && e.classList.contains('keyHighlight')){
e1.classList.add("keyHighlight")
} else {
e1.classList.remove("keyHighlight")
}
}
})
})
.keyHighlight {fill: #6CAD0E; opacity: 1;}
.keyHighlight1 {fill: #6CAD0E; opacity: 1;}
/* Create two equal columns that float next to each other */
.column {
float: left;
width: 50%;
padding: 10px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
.row {
display: flex;
}
<html>
<head>
<meta charset="utf-8">
<title>duplicate test</title>
</head>
<body>
<div class="row">
<div class="column">
<p>SVG1</p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="200" height="250" id="fingering">
<ellipse class="ellipsoid" id="LH1" cx="66" cy="45" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
<ellipse class="ellipsoid" id="LH2" cx="66" cy="95" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
<ellipse class="ellipsoid" id="LH3" cx="66" cy="145" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
</svg>
</div>
<div class="column">
<p>SVG2</p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="200" height="250" id="fingering1">
<ellipse class="ellipsoid" id="LH1-1" cx="66" cy="45" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
<ellipse class="ellipsoid" id="LH2-1" cx="66" cy="95" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
<ellipse class="ellipsoid" id="LH3-1" cx="66" cy="145" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
</svg>
</div>
</div>
</body>
</html>
为每个省略号堆栈使用 W3C 标准 Web 组件<svg-circle-stack>
。
(所有现代浏览器都支持,IE 不支持)
WebComponent 在每个 Ellipse 上注册侦听器以处理 click
;
并在每次点击 时向所有 省略号发送带有 index
负载的 Event
。
相同索引的省略号也会切换颜色。
没关系什么时候你加多了<svg-circle-stack>
;使用 Events
确保它们始终有效。
当 <svg-circle-stack>
从 DOM 中删除时,它会清除在 document
上设置在其自身范围之外的侦听器。 (自动清理点击处理程序)
定位 你自己 使用 CSS 网格或 flexbox。
<style type="text/css">
.highlight { fill: gold }
svg-circle-stack { width:90px; height:180px; display:inline-block; background:pink }
svg-circle-stack ellipse { fill:white; stroke:black; pointer-events:all; cursor:pointer }
svg-circle-stack ellipse:hover { stroke:lightgreen }
</style>
<svg-circle-stack></svg-circle-stack>
<svg-circle-stack></svg-circle-stack>
<svg-circle-stack></svg-circle-stack>
<svg-circle-stack></svg-circle-stack>
<script>
customElements.define("svg-circle-stack", class extends HTMLElement {
connectedCallback() {
this.innerHTML = `<svg viewBox="15 0 100 190">
<ellipse cx="66" cy="45" rx="20" ry="20" />
<ellipse cx="66" cy="95" rx="20" ry="20" />
<ellipse cx="66" cy="145" rx="20" ry="20" />
</svg>`;
this.ln = this.querySelectorAll("ellipse").forEach((ellipse, index) => {
ellipse.onclick = (evt) => {
ellipse.dispatchEvent(new CustomEvent("ellipseClick",
{ bubbles:true, detail:index }))
}
return document.addEventListener("ellipseClick", (evt) => {
if (evt.detail == index) ellipse.classList.toggle("highlight");
})
})
}
disconnectedCallback() {
this.ln.forEach(ellipse => document.removeEventLister("ellipseClick"))
}
});
</script>
我有两个具有相同元素的 SVG。当我单击 SVG1 上的一个元素时,它会通过切换 CSS class 来突出显示。我希望 SGV2 上的相同元素自动突出显示(注意:稍后,我希望能够通过单击 SVG2 来更改 SVG2 上突出显示的内容)。
我已经尝试进行转换 table 所以当我使用 getElementById 捕获 SVG1 点击时,该 ID 被转换为 SVG2 上的相应 ID,然后应用 CSS class,但这不起作用。关于如何执行此操作有什么建议吗?
这是一个 JSfiddle - https://jsfiddle.net/scottmclaughlin/gynzou0t/21/
// changes colour of the clicked element
function highlighter () {
var ellipses = document.getElementById(this.id);
ellipses.classList.toggle("keyHighlight");
// also duplicate highlight on second svg
let duplicateEllipses = (ellipses) => translateTable[ellipses];
duplicateEllipses.classList.toggle("keyHighlight1");
}
不相关,SVG 应该并排放置,但 column/row CSS 出于某种原因不正确。
ellipses
是一个元素而不是 id,你的 duplicateEllipses
用法很奇怪,它被定义为一个函数,但用作一个元素。我认为你应该做的逻辑方式是这样的:
let duplicateEllipses = document.getElementById(translateTable[this.id]);
duplicateEllipses.classList.toggle("keyHighlight1");
不是更简洁的方法,但您可以尝试:
let ellipses = document.querySelectorAll('.ellipsoid')
ellipses.forEach(e => {
e.addEventListener('click', function() {
e.classList.toggle("keyHighlight")
if (e.id.slice(-2) !== '-1') {
let e1 = document.querySelector(`#${e.id}-1`)
if (e1.classList.contains('keyHighlight') && e.classList.contains('keyHighlight')) {
e1.classList.add("keyHighlight")
} else if (!e1.classList.contains('keyHighlight') && e.classList.contains('keyHighlight')){
e1.classList.add("keyHighlight")
} else {
e1.classList.remove("keyHighlight")
}
}
})
})
.keyHighlight {fill: #6CAD0E; opacity: 1;}
.keyHighlight1 {fill: #6CAD0E; opacity: 1;}
/* Create two equal columns that float next to each other */
.column {
float: left;
width: 50%;
padding: 10px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
.row {
display: flex;
}
<html>
<head>
<meta charset="utf-8">
<title>duplicate test</title>
</head>
<body>
<div class="row">
<div class="column">
<p>SVG1</p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="200" height="250" id="fingering">
<ellipse class="ellipsoid" id="LH1" cx="66" cy="45" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
<ellipse class="ellipsoid" id="LH2" cx="66" cy="95" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
<ellipse class="ellipsoid" id="LH3" cx="66" cy="145" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
</svg>
</div>
<div class="column">
<p>SVG2</p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="200" height="250" id="fingering1">
<ellipse class="ellipsoid" id="LH1-1" cx="66" cy="45" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
<ellipse class="ellipsoid" id="LH2-1" cx="66" cy="95" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
<ellipse class="ellipsoid" id="LH3-1" cx="66" cy="145" rx="20" ry="20" fill="#ffffff" stroke="#000000" pointer-events="all"/>
</svg>
</div>
</div>
</body>
</html>
为每个省略号堆栈使用 W3C 标准 Web 组件<svg-circle-stack>
。
(所有现代浏览器都支持,IE 不支持)
WebComponent 在每个 Ellipse 上注册侦听器以处理 click
;
并在每次点击 时向所有 省略号发送带有 index
负载的 Event
。
相同索引的省略号也会切换颜色。
没关系什么时候你加多了<svg-circle-stack>
;使用 Events
确保它们始终有效。
当 <svg-circle-stack>
从 DOM 中删除时,它会清除在 document
上设置在其自身范围之外的侦听器。 (自动清理点击处理程序)
定位 你自己 使用 CSS 网格或 flexbox。
<style type="text/css">
.highlight { fill: gold }
svg-circle-stack { width:90px; height:180px; display:inline-block; background:pink }
svg-circle-stack ellipse { fill:white; stroke:black; pointer-events:all; cursor:pointer }
svg-circle-stack ellipse:hover { stroke:lightgreen }
</style>
<svg-circle-stack></svg-circle-stack>
<svg-circle-stack></svg-circle-stack>
<svg-circle-stack></svg-circle-stack>
<svg-circle-stack></svg-circle-stack>
<script>
customElements.define("svg-circle-stack", class extends HTMLElement {
connectedCallback() {
this.innerHTML = `<svg viewBox="15 0 100 190">
<ellipse cx="66" cy="45" rx="20" ry="20" />
<ellipse cx="66" cy="95" rx="20" ry="20" />
<ellipse cx="66" cy="145" rx="20" ry="20" />
</svg>`;
this.ln = this.querySelectorAll("ellipse").forEach((ellipse, index) => {
ellipse.onclick = (evt) => {
ellipse.dispatchEvent(new CustomEvent("ellipseClick",
{ bubbles:true, detail:index }))
}
return document.addEventListener("ellipseClick", (evt) => {
if (evt.detail == index) ellipse.classList.toggle("highlight");
})
})
}
disconnectedCallback() {
this.ln.forEach(ellipse => document.removeEventLister("ellipseClick"))
}
});
</script>