循环遍历 div 并添加 onmouseover

问题描述

真的很难解决这个问题,虽然我知道解决方案应该很简单。

  1. 我有一组 div
  2. 每个 div 包含一个图标
  3. 在鼠标悬停时,我希望出现一个弹出窗口。
  4. 鼠标移开,消失。

我已经通过 DOM 操作将我的 div 注入到我的 HTML 中,我认为这是问题的一部分。 (但由于我正在使用的应用程序,我必须这样做。这无法更改)。

然后我通过 setAtttribute 设置了我的鼠标悬停功能setAttribute("onmouSEOver","triggerPopUp(event)"); `

但我一直收到错误

未捕获的类型错误:无法读取 null 的属性“classList”

我不知道如何让它工作......

悬停时,我试图获取弹出窗口的 ID 并删除一个类以使其出现: document.getElementById(event.target.id).classList.remove("refund-popup");

任何提示都会有所帮助!

这是一个代码示例:

let getFirstCardOption  = document.querySelectorAll(".getFirstCardOption");

triggerPopUp = (event) => {
    // let popup = document.querySelector(".callout__content.top.right.refund-popup");
    // popup.classList.remove("refund-popup")
    console.log("event",event.target.id);
    event.target.classList.remove("refund-popup");
};

closePopUp = (event) => {
    // let popup = document.querySelector(".callout__content.top.right");
    // popup.classList.add("refund-popup");
    console.log("event",event.target.id);
    event.target.classList.add("refund-popup");
};

for (let i = 0; i < getFirstCardOption.length; i++) {

  console.log(i);
  let priceParent = document.querySelectorAll(".price")[i];
  let pricePillsContainer = document.querySelectorAll(".price__pills")[i];

  let depositMessageContainer = document.createElement("div");
  depositMessageContainer.classList.add("price__desposit-message");
  priceParent.insertBefore(depositMessageContainer,pricePillsContainer);

  // Container One
  let depositIconDivOne = document.createElement("div");
  depositIconDivOne.classList.add("deposit-icon");
  depositMessageContainer.appendChild(depositIconDivOne);

  let depositcopyOne = document.createElement("p");
  depositcopyOne.classList.add("deposit-copy");
  depositcopyOne.innerHTML = "Hover over the black icon/square below";
  depositIconDivOne.appendChild(depositcopyOne);

  // ADD POPUP CONTAINER
  let calloutContainer = document.createElement("div");
  calloutContainer.classList.add("callout__container","refund");
  calloutContainer.setAttribute("onmouSEOver","triggerPopUp(event)");
  calloutContainer.setAttribute("onmouSEOut","closePopUp(event)");
  calloutContainer.setAttribute("id",`refund-${[i]}`);
  depositIconDivOne.appendChild(calloutContainer);

  let calloutParent = document.createElement("div");
  calloutParent.classList.add("callout__parent");
  calloutContainer.appendChild(calloutParent);

  let calloutIcon = document.createElement("i");
  calloutIcon.classList.add("more-info");
  calloutParent.appendChild(calloutIcon);

  let calloutSVG = document.createElement("svg");
  calloutSVG.setAttribute("aria-hidden","true");
  calloutSVG.setAttribute("height","16px");
  calloutSVG.setAttribute("width","16px");
  calloutSVG.setAttribute("focusable","false");
  calloutSVG.setAttribute("data-prefix","fas");
  calloutSVG.setAttribute("data-icon","info-circle");
  calloutSVG.setAttribute("class","svg-inline--fa fa-info-circle fa-w-16");
  calloutSVG.setAttribute("role","img");
  calloutSVG.setAttribute("xmlns","http://www.w3.org/2000/svg");
  calloutSVG.setAttribute("viewBox","0 0 512 512");
  calloutIcon.appendChild(calloutSVG);

  let calloutPath = document.createElement("path");
  calloutPath.setAttribute("fill","currentColor");
  calloutPath.setAttribute("d","M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z");
  calloutSVG.appendChild(calloutPath);

  // Add POPUP DIV AND MESSAGE
  let calloutContent = document.createElement("div");
  calloutContent.classList.add("callout__content","top","right","refund-popup");
  calloutContent.setAttribute("id",`refund-${[i]}`);
  calloutContent.innerText = "Pop is appearing!"
  calloutContainer.appendChild(calloutContent);
};
.price {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    align-items: flex-end;
    margin-bottom: 10px;
    border: 1px solid red;
}

.price__desposit-message {
    background-color: #F0FFED;
    color: #55A446;
    padding: 10px;
}

.deposit-icon:nth-child(1) {
    margin-bottom: 10px;
}

deposit-icon {
    display: flex;
    flex-direction: row;
    flex-wrap: Nowrap;
    align-items: flex-start;
    border: 1px
}

.callout__container .callout__parent {
    display: inline-block;
    line-height: 45px;
    cursor: pointer;
    border: 1px solid black;
    width: 20px;
    height: 20px;
}

callout__container {
    position: relative;
    display: inline-flex;
    align-items: center;
    max-height: 45px;
}

.refund-popup {
    display: none;
}
<div class="getFirstCardOption">
  <div class="price">
    <div class="price__pills"></div>
  </div>
</div>

<div class="getFirstCardOption">
  <div class="price">
    <div class="price__pills"></div>
  </div>
</div>

解决方法

我认为您应该使用 event.target.classList.remove("refund-popup"); 而不是 document.getElementById(event.target.id).classList.remove("refund-popup");,因为您已经拥有该元素,无需再次选择它。

,

错误是因为黑盒上没有id,容器上有id。因此,当您将鼠标悬停在 (onmouseover ) 黑框上或导航离开黑框 (onmouseout ) 时,您将获得 undefined 的 ID。 I. 这种情况下你需要找到父级的id。

如果 triggerPopUp 上的 id 未定义,我对您的函数 closePopUp event.target.id 进行了一个小的更改以获取父级的 id

const id = event.target.id || event.target.parentNode.id

let getFirstCardOption  = document.querySelectorAll(".getFirstCardOption");

triggerPopUp = (event) => {
    // let popup = document.querySelector(".callout__content.top.right.refund-popup");
    // popup.classList.remove("refund-popup")
    const id = event.target.id || event.target.parentNode.id
    console.log({id})
    document.getElementById(id).classList.remove("refund-popup");
};

closePopUp = (event) => {
    // let popup = document.querySelector(".callout__content.top.right");
    // popup.classList.add("refund-popup");
    const id = event.target.id || event.target.parentNode.id
    console.log({id})
    document.getElementById(id).classList.add("refund-popup");
};

for (let i = 0; i < getFirstCardOption.length; i++) {

  console.log(i);
  let priceParent = document.querySelectorAll(".price")[i];
  let pricePillsContainer = document.querySelectorAll(".price__pills")[i];

  let depositMessageContainer = document.createElement("div");
  depositMessageContainer.classList.add("price__desposit-message");
  priceParent.insertBefore(depositMessageContainer,pricePillsContainer);

  // Container One
  let depositIconDivOne = document.createElement("div");
  depositIconDivOne.classList.add("deposit-icon");
  depositMessageContainer.appendChild(depositIconDivOne);

  let depositCopyOne = document.createElement("p");
  depositCopyOne.classList.add("deposit-copy");
  depositCopyOne.innerHTML = "Hover over the black icon/square below";
  depositIconDivOne.appendChild(depositCopyOne);

  // ADD POPUP CONTAINER
  let calloutContainer = document.createElement("div");
  calloutContainer.classList.add("callout__container","refund");
  calloutContainer.setAttribute("onmouseover","triggerPopUp(event)");
  calloutContainer.setAttribute("onmouseout","closePopUp(event)");
  calloutContainer.setAttribute("id",`refund-${[i]}`);
  depositIconDivOne.appendChild(calloutContainer);

  let calloutParent = document.createElement("div");
  calloutParent.classList.add("callout__parent");
  calloutContainer.appendChild(calloutParent);

  let calloutIcon = document.createElement("i");
  calloutIcon.classList.add("more-info");
  calloutParent.appendChild(calloutIcon);

  let calloutSVG = document.createElement("svg");
  calloutSVG.setAttribute("aria-hidden","true");
  calloutSVG.setAttribute("height","16px");
  calloutSVG.setAttribute("width","16px");
  calloutSVG.setAttribute("focusable","false");
  calloutSVG.setAttribute("data-prefix","fas");
  calloutSVG.setAttribute("data-icon","info-circle");
  calloutSVG.setAttribute("class","svg-inline--fa fa-info-circle fa-w-16");
  calloutSVG.setAttribute("role","img");
  calloutSVG.setAttribute("xmlns","http://www.w3.org/2000/svg");
  calloutSVG.setAttribute("viewBox","0 0 512 512");
  calloutIcon.appendChild(calloutSVG);

  let calloutPath = document.createElement("path");
  calloutPath.setAttribute("fill","currentColor");
  calloutPath.setAttribute("d","M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z");
  calloutSVG.appendChild(calloutPath);

  // Add POPUP DIV AND MESSAGE
  let calloutContent = document.createElement("div");
  calloutContent.classList.add("callout__content","top","right","refund-popup");
  calloutContent.setAttribute("id",`refund-${[i]}`);
  calloutContent.innerText = "Pop is appearing!"
  calloutContainer.appendChild(calloutContent);
};
.price {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    align-items: flex-end;
    margin-bottom: 10px;
    border: 1px solid red;
}

.price__desposit-message {
    background-color: #F0FFED;
    color: #55A446;
    padding: 10px;
}

.deposit-icon:nth-child(1) {
    margin-bottom: 10px;
}

deposit-icon {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: flex-start;
    border: 1px
}

.callout__container .callout__parent {
    display: inline-block;
    line-height: 45px;
    cursor: pointer;
    border: 1px solid black;
    width: 20px;
    height: 20px;
}

callout__container {
    position: relative;
    display: inline-flex;
    align-items: center;
    max-height: 45px;
}

.refund-popup {
    display: none;
}
<div class="getFirstCardOption">
  <div class="price">
    <div class="price__pills"></div>
  </div>
</div>

<div class="getFirstCardOption">
  <div class="price">
    <div class="price__pills"></div>
  </div>
</div>

let getFirstCardOption  = document.querySelectorAll(".getFirstCardOption");

triggerPopUp = (event) => {
    // let popup = document.querySelector(".callout__content.top.right.refund-popup");
    // popup.classList.remove("refund-popup")
    console.log("event",event.target.id);
    event.target.classList.remove("refund-popup");
};

closePopUp = (event) => {
    // let popup = document.querySelector(".callout__content.top.right");
    // popup.classList.add("refund-popup");
    console.log("event",event.target.id);
    event.target.classList.add("refund-popup");
};

for (let i = 0; i < getFirstCardOption.length; i++) {

  console.log(i);
  let priceParent = document.querySelectorAll(".price")[i];
  let pricePillsContainer = document.querySelectorAll(".price__pills")[i];

  let depositMessageContainer = document.createElement("div");
  depositMessageContainer.classList.add("price__desposit-message");
  priceParent.insertBefore(depositMessageContainer,`refund-${[i]}`);
  calloutContent.innerText = "Pop is appearing!"
  calloutContainer.appendChild(calloutContent);
};
.price {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    align-items: flex-end;
    margin-bottom: 10px;
    border: 1px solid red;
}

.price__desposit-message {
    background-color: #F0FFED;
    color: #55A446;
    padding: 10px;
}

.deposit-icon:nth-child(1) {
    margin-bottom: 10px;
}

deposit-icon {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: flex-start;
    border: 1px
}

.callout__container .callout__parent {
    display: inline-block;
    line-height: 45px;
    cursor: pointer;
    border: 1px solid black;
    width: 20px;
    height: 20px;
}

callout__container {
    position: relative;
    display: inline-flex;
    align-items: center;
    max-height: 45px;
}

.refund-popup {
    display: none;
}
<div class="getFirstCardOption">
  <div class="price">
    <div class="price__pills"></div>
  </div>
</div>

<div class="getFirstCardOption">
  <div class="price">
    <div class="price__pills"></div>
  </div>
</div>