【问题标题】:Event Delegation - Element Style Issues - Javascript事件委托 - 元素样式问题 - 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" alt="" class="giphyImg__Front giphyImg__Front1">
        <div class="giphyImg__Back giphyImg__Back1"></div>
    </div>
    <div class="giphyImg">
        <img src="img2.png" alt="" class="giphyImg__Front giphyImg__Front2">
        <div class="giphyImg__Back giphyImg__Back2"></div>
    </div>
    <div class="giphyImg">
        <img src="img3.png" alt="" class="giphyImg__Front giphyImg__Front3">
        <div class="giphyImg__Back giphyImg__Back3"></div>
    </div>
</div>

【问题讨论】:

  • 您每次都在设置相同的frontPanelbackPanel 元素的样式。这只是每个变量的一个元素。

标签: javascript events delegation


【解决方案1】:

您正在使用frontPanelbackPanel 的全局值,它们不会根据您单击的图像而改变。

您需要将frontPanelbackPanel设置为与被点击元素相同的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 类之外还需要进行任何检查,肯定会改变
  • 就此而言,似乎不需要对Front1Front2等进行单独检查。它可以委托给giphyImg__FrontgiphyImg__Back
  • 但我将日志消息视为每个块中不同操作的占位符。
【解决方案2】:

简单地做

<div class="giphyContainer">
  <div class="giphyImg">
    <img src="img1.png" alt="" class="giphyImg__Front">
    <div class="giphyImg__Back></div>
  </div>
  <div class="giphyImg">
    <img src="img2.png" alt="" class="giphyImg__Front">
    <div class="giphyImg__Back"></div>
  </div>
  <div class="giphyImg">
    <img src="img3.png" alt="" 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" alt="" >
  </div>
  <div class="giphyImg front">
    <img src="https://picsum.photos/id/1019/160/200" alt="" >
  </div>
  <div class="giphyImg front">
    <img src="https://picsum.photos/id/1016/160/200" alt="" >
  </div>
</div>

【讨论】:

    猜你喜欢
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多