事件委托 - 元素样式问题 - Javascript
Posted
技术标签:
【中文标题】事件委托 - 元素样式问题 - Javascript【英文标题】:Event Delegation - Element Style Issues - Javascript 【发布时间】:2021-11-02 03:59:08 【问题描述】:有一个问题,我可以单击每个单独的元素,然后目标元素在被单击时返回,但是在应用样式时,它仅适用于第一个元素,而不适用于任何其他目标元素。
事件委托的工作原理如上所述
下面是一个单独的书面示例来尝试调试这个问题,但我很难过
giphyContainer.addEventListener('click', (e) =>
console.log(e.target);
if (e.target.classList.contains("giphyImg__Front1"))
console.log("clicked! 1")
frontPanel.style.zIndex = -3;
backPanel.style.zIndex = 3;
if (e.target.classList.contains("giphyImg__Front2"))
console.log("clicked! 2")
frontPanel.style.zIndex = -3;
backPanel.style.zIndex = 3;
if (e.target.classList.contains("giphyImg__Front3"))
console.log("clicked! 3")
frontPanel.style.zIndex = -3;
backPanel.style.zIndex = 3;
if (e.target.classList.contains("giphyImg__Back1"))
frontPanel.style.zIndex = 3;
backPanel.style.zIndex = -3;
if (e.target.classList.contains("giphyImg__Back2"))
frontPanel.style.zIndex = 3;
backPanel.style.zIndex = -3;
if (e.target.classList.contains("giphyImg__Back3"))
frontPanel.style.zIndex = 3;
backPanel.style.zIndex = -3;
)
<div class="giphyContainer">
<div class="giphyImg">
<img src="img1.png" class="giphyImg__Front giphyImg__Front1">
<div class="giphyImg__Back giphyImg__Back1"></div>
</div>
<div class="giphyImg">
<img src="img2.png" class="giphyImg__Front giphyImg__Front2">
<div class="giphyImg__Back giphyImg__Back2"></div>
</div>
<div class="giphyImg">
<img src="img3.png" class="giphyImg__Front giphyImg__Front3">
<div class="giphyImg__Back giphyImg__Back3"></div>
</div>
</div>
【问题讨论】:
您每次都在设置相同的frontPanel
和backPanel
元素的样式。这只是每个变量的一个元素。
【参考方案1】:
您正在使用frontPanel
和backPanel
的全局值,它们不会根据您单击的图像而改变。
您需要将frontPanel
和backPanel
设置为与被点击元素相同的DIV中的前后图像。
giphyContainer.addEventListener('click', (e) =>
console.log(e.target);
let frontPanel = e.target.closest("div.giphyImg").querySelector(".giphyImg__Front");
let backPanel = e.target.closest("div").querySelector(".giphyImg__Back");
if (e.target.classList.contains("giphyImg__Front1"))
console.log("clicked! 1")
frontPanel.style.zIndex = -3;
backPanel.style.zIndex = 3;
if (e.target.classList.contains("giphyImg__Front2"))
console.log("clicked! 2")
frontPanel.style.zIndex = -3;
backPanel.style.zIndex = 3;
if (e.target.classList.contains("giphyImg__Front3"))
console.log("clicked! 3")
frontPanel.style.zIndex = -3;
backPanel.style.zIndex = 3;
if (e.target.classList.contains("giphyImg__Back1"))
frontPanel.style.zIndex = 3;
backPanel.style.zIndex = -3;
if (e.target.classList.contains("giphyImg__Back2"))
frontPanel.style.zIndex = 3;
backPanel.style.zIndex = -3;
if (e.target.classList.contains("giphyImg__Back3"))
frontPanel.style.zIndex = 3;
backPanel.style.zIndex = -3;
)
【讨论】:
因为重复相同的计算。此外代码可以优化为:const classList = e.target.classList; if (classList.contains("giphyImg__Front1") || classList.contains("giphyImg__Front2") || classList.contains("giphyImg__Front3")) frontPanel.style.zIndex = -3; backPanel.style.zIndex = 3; else frontPanel.style.zIndex = 3; backPanel.style.zIndex = -3;
是的,这里有很多 DRY 可能。我假设在实际应用程序中实际上还有更多内容,并且每个 if 块确实需要做一些不同的事情。
对。我只是建议查看当前的代码示例。如果除了 Front 和 Back 类之外还需要进行任何检查,肯定会改变
就此而言,似乎不需要对Front1
、Front2
等进行单独检查。它可以委托给giphyImg__Front
和giphyImg__Back
但我将日志消息视为每个块中不同操作的占位符。【参考方案2】:
简单地做
<div class="giphyContainer">
<div class="giphyImg">
<img src="img1.png" class="giphyImg__Front">
<div class="giphyImg__Back></div>
</div>
<div class="giphyImg">
<img src="img2.png" class="giphyImg__Front">
<div class="giphyImg__Back"></div>
</div>
<div class="giphyImg">
<img src="img3.png" class="giphyImg__Front">
<div class="giphyImg__Back"></div>
</div>
</div>
const giphyContainer = document.querySelector('.giphyContainer')
giphyContainer.onclick = (target) =>
if (!target.matches('.giphyImg__Back,.giphyImg__Front')) return
let
parent = target.closest('div.giphyImg')
, isFront = target.matches('.giphyImg__Front')
;
parent.querySelector('.giphyImg__Front').style.zIndex = isFront ? -3 : 3
parent.querySelector('.giphyImg__Back').style.zIndex = isFront ? 3 : -3
但是做起来要简单得多:
const giphyContainer = document.querySelector('.giphyContainer')
giphyContainer.onclick = (target) =>
if (!target.matches('.giphyImg, .giphyImg > img')) return
target.closest('div.giphyImg').classList.toggle('front')
div.giphyImg
display : inline-block;
margin : 10px 5px;
cursor : pointer;
background : teal;
font-size : 0;
div.giphyImg > img visibility: hidden;
div.giphyImg.front > img visibility: visible;
<div class="giphyContainer">
<div class="giphyImg ">
<img src="https://picsum.photos/id/1015/160/200" >
</div>
<div class="giphyImg front">
<img src="https://picsum.photos/id/1019/160/200" >
</div>
<div class="giphyImg front">
<img src="https://picsum.photos/id/1016/160/200" >
</div>
</div>
【讨论】:
以上是关于事件委托 - 元素样式问题 - Javascript的主要内容,如果未能解决你的问题,请参考以下文章