javascript - 用 Accordion 连接 svg rect

标签 javascript html css svg accordion

我有一个 svg 图像,鼠标悬停在四个矩形元素上,还有一个带有四个按钮的 Accordion ,用 javascript 完成。我想通过同时将它们悬停(矩形和按钮 Accordion )来连接每个元素,然后单击 svg 矩形将打开按钮 Accordion ,单击 Accordion 将填充矩形。你可以在这里查看我的 fiddle :https://jsfiddle.net/pfrutuoso/zcsj8g05/2/ 这是我的 html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div class="wrapper">
        <div class="stage_info">
            <button class="accordion">Stage 1</button>
            <div class="panel">
                <p>Information here..</p>
            </div>

            <button class="accordion">Stage 2</button>
            <div class="panel">
                <p>Information here..</p>
            </div>
            <button class="accordion">Stage 3</button>
            <div class="panel">
                <p>Information here..</p>
            </div>
            <button class="accordion">Stage 4</button>
            <div class="panel">
                <p>Information here..</p>
            </div>
        </div>
        <div class="stage_img">
            <map id="big_stage">
            <svg version="1.1" id="stadium" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            width="100%" height="100%" viewBox="0 0 456.122 451.02" enable-background="new 0 0 456.122 451.02"
            xml:space="preserve">
       <rect id="stage4" x="25.51" y="25.51" fill="#1C6131" width="200" height="200"/>
       <rect id="stage3" x="230.612" y="25.51" fill="#1C6131" width="200" height="200"/>
       <rect id="stage2" x="25.51" y="229.592" fill="#1C6131" width="200" height="200"/>
       <rect id="stage1" x="230.612" y="229.592" fill="#1C6131" width="200" height="200"/>
       </svg>
           </map>

        </div>
    </div>
</body>

</html>

我的CSS:

.accordion {
    background-color: #eee;
    color: #444;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    text-align: left;
    border: none;
    outline: none;
    transition: 0.4s;
}

.active,
.accordion:hover {
    background-color: #ccc;
}

.panel {
    padding: 0 18px;
    background-color: white;
    display: none;
    overflow: hidden;
}

.wrapper {
    display: inline-block;
    max-width: 1140px;
    margin: 0 auto;
    width: 100%;
    text-align: center;
}

.stage_info,
.stage_img {
    display: inline-block;
    width: calc(50% - 80px);
    vertical-align: top;
}

rect {
    cursor: pointer;
    z-index: 999;
    position: relative;
}

rect:hover {
    fill: #ccc;
    pointer-events: all;
}

还有我的javascript:

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function() {
        this.classList.toggle("active");
        var panel = this.nextElementSibling;
        if (panel.style.display === "block") {
            panel.style.display = "none";
        } else {
            panel.style.display = "block";
        }
    });
}

最佳答案

我尝试尽可能按程序进行,因为这似乎是您在 JS 中想要的。 我使用相应 id 元素的 rect 将 value 属性添加到您的舞台按钮,并添加了一个名为 classgrey,其属性与悬停时应用的属性相同。

	let stgInf = document.querySelector(".stage_info");
	let svg = document.querySelector("#stadium");

	function onClick(num) {
		let acc = stgInf.querySelector(`.accordion:nth-of-type(${num})`);
		let panel = acc.nextElementSibling;
		let rect = svg.querySelector(`rect#${acc.getAttribute("value")}`);
		return () => {
			acc.classList.toggle("active");
			if (acc.classList.contains("active")) {
				panel.style.display = "block";
				rect.classList.add("grey");
			} else {
				panel.style.display = "none";
				rect.classList.remove("grey");
			}
		}
	}

	function hover(num) {
		let acc = stgInf.querySelector(`.accordion:nth-of-type(${num})`);
		let rect = svg.querySelector(`rect#${acc.getAttribute("value")}`);
		return (event) => {
			if (event.type === "mouseenter") {
				acc.classList.add("grey");
				rect.classList.add("grey");
			} else if (!acc.classList.contains("active")) {
				acc.classList.remove("grey");
				rect.classList.remove("grey");
			}
		}
	}

	let accs = stgInf.querySelectorAll(".accordion");
	let i = 1;
	for (let acc of accs) {
		let rect = svg.querySelector(`rect#${acc.getAttribute("value")}`);
		acc.addEventListener("click", onClick(i));
		acc.addEventListener("mouseenter", hover(i));
		acc.addEventListener("mouseout", hover(i));
		rect.addEventListener("click", onClick(i));
		rect.addEventListener("mouseenter", hover(i));
		rect.addEventListener("mouseout", hover(i));
		++i;
	}
		.accordion {
			background-color: #eee;
			color: #444;
			cursor: pointer;
			padding: 18px;
			width: 100%;
			text-align: left;
			border: none;
			outline: none;
			transition: 0.4s;
		}

		.panel {
			padding: 0 18px;
			background-color: white;
			display: none;
			overflow: hidden;
		}

		.wrapper {
			display: inline-block;
			max-width: 1140px;
			margin: 0 auto;
			width: 100%;
			text-align: center;
		}
		.stage_info,
		.stage_img {
			display: inline-block;
			width: calc(50% - 80px);
			vertical-align: top;
		}

		rect {
			cursor: pointer;
			z-index: 999;
			position: relative;
		}

		.grey,
		.active,
		.accordion:hover,
		rect:hover {
			fill: #ccc;
			background-color: #ccc;
			pointer-events: all;
		}
<div class="wrapper">
  <div class="stage_info">
    <button class="accordion" value="stage1">Stage 1</button>
    <div class="panel">
      <p>Information here..</p>
    </div>
    <button class="accordion" value="stage2">Stage 2</button>
    <div class="panel">
      <p>Information here..</p>
    </div>
    <button class="accordion" value="stage3">Stage 3</button>
    <div class="panel">
      <p>Information here..</p>
    </div>
    <button class="accordion" value="stage4">Stage 4</button>
    <div class="panel">
      <p>Information here..</p>
    </div>
  </div>
  <div class="stage_img">
    <map id="big_stage">
            <svg version="1.1" id="stadium" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            width="100%" height="100%" viewBox="0 0 456.122 451.02" enable-background="new 0 0 456.122 451.02"
            xml:space="preserve">
				<rect id="stage4" x="25.51" y="25.51" fill="#1C6131" width="200" height="200"/>
				<rect id="stage3" x="230.612" y="25.51" fill="#1C6131" width="200" height="200"/>
				<rect id="stage2" x="25.51" y="229.592" fill="#1C6131" width="200" height="200"/>
				<rect id="stage1" x="230.612" y="229.592" fill="#1C6131" width="200" height="200"/>
			</svg>
           </map>
  </div>
</div>

编辑

除了点击监听器之外,我还通过添加 mouseenter 和 mouseout 事件监听器来实现您在评论中提到的悬停功能。

关于javascript - 用 Accordion 连接 svg rect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59755547/

相关文章:

javascript - 获取跨域 iframe 的响应状态码?

html - 如何一起使用 float 和 margin

html - 为什么框中有未知的边距/填充?

html - 绝对定位的 div 不会一直延伸到 body 下方

javascript - 哈巴狗/ Jade : onClick call function and pass param

javascript - 更改使用 JavaScript 选中的复选框

javascript - 限制滚动到 DIV

javascript - 将标记标签添加到谷歌地图标记

javascript - CSS 属性拒绝使用 JavaScript 或 Jquery 进行更改

html - 加载 gif 时主屏幕保持灰色