首页 > 解决方案 > 如何在事件处理程序中执行 map() 函数

问题描述

我正在用 vanilla JS 建立一个律师事务所网站,其中涉及很多内容页面。当用户点击不同的链接时,我试图让一个页面显示不同的内容页面。我这样做是通过让 html 已经使用默认属性 display: none 编写的,并且当用户单击链接时,目标链接可以动态更改该元素的 CSS 以显示:块,同时确保所有其他元素都是设置为显示:无,以便一次显示一个。我有一个包含所有内容元素的数组,并使用 splice 从映射函数中删除目标元素,该函数应该将所有元素设置为显示:无,我将目标元素设置为显示:块。问题是当我在事件处理程序中使用它时地图没有执行,但是当我在事件处理程序之外使用它时它确实有效。它没有抛出任何错误,只是没有将显示设置为无。

我尝试了不同的方法来获得相同的结果,例如使用 forEach() 函数,但这也与映射的结果相似。它没有抛出任何错误,但它不起作用。我尝试使用 display: none 创建一个通用类,并使用 map 或 forEach 将该类动态添加到所有目标元素,但这也不起作用。

此外,拼接不起作用,因为它一直告诉我拼接不是一个函数。经过大量试验和错误以及大量研究后,我能够解决此问题的唯一方法是使用 document.getElementById() 手动定位每个元素,这是非常低效的。当我使用 document.getElementsByClassName() 或当我使用 document.querySelectorAll() 时,它从来没有工作过

问题一:拼接不是函数

抓取所有元素并解构它们以提高效率

let contentText = document.getElementsByClassName('content-text');

let [immigrationText, contractsText, divorceText, debtCollectionText, escrowText, expungementText, mediationText, personalInjuryText, willsAndTrustsText] = contentText;

在事件处理程序中使用拼接

let immigrationEvent = () => {  
      contentText.splice(0, 1);  
      contentText.map((link) => link.style.display = 'none');  
      immigrationText.style.display = 'block';  
    }; 

错误

Uncaught TypeError: contentText.splice is not a function
    at HTMLLIElement.immigrationEvent

问题 2:地图功能不执行

抓取所有链接并解构它们。这样用户就可以点击这些链接,当他们点击它们时,它应该映射所有当时没有被调用的链接,并且应该将 css 显示更改为无

let contentLinks = Array.from(document.getElementsByClassName('side- 
 nav-items'));

let [immigration, contracts, divorce, debtCollection, escrow, 
 expungement, mediation, personalInjury, willsAndTrusts] = 
 contentLinks;

抓取所有包含我们希望显示的内容的元素,并解构它们,并将它们添加到名为 contentText 的数组中

let contentText = Array.from(document.getElementsByClassName('content- 
 text'));

let [immigrationText, contractsText, divorceText, debtCollectionText, 
 escrowText, expungementText, mediationText, personalInjuryText, 
 willsAndTrustsText] = contentText;

拼接数组以排除用户当前正在调用的页面,然后映射其余页面,以便他们将显示属性切换为无。这当然是事件处理函数

let immigrationEvent = () => {
 contentText.splice(0, 1);
 contentText.map((link) => link.style.display = 'none');
 immigrationText.style.display = 'block';
};

let contractsEvent = () => {
 contentText.splice(1, 1);
 contentText.map((link) => link.classList.add('content-hide'));
 contractsText.style.display = 'block';
};

调用事件处理函数。我包括2个例子

immigration.addEventListener('click', immigrationEvent, false);
contracts.addEventListener('click', contractsEvent, false);

问题 1:预期结果,当我使用某种类型的全选功能时,我是否希望拼接工作,但它仅在我使用它们作为目标时才有效

getElementById()

问题 2:我希望地图功能将数组中的所有目标元素设置为不显示。相反,当我单击链接时,它会将元素添加到同一页面,但不会隐藏先前的元素

标签: javascriptevent-handlingmap-function

解决方案


这会导致“TypeError:contentText.splice 不是函数”:

let contentText = document.getElementsByClassName('content-text');
contentText.splice(0, 1);  

...因为getElementsByClassName返回“一个类似数组的对象”(一个“live” HTMLCollection,它会随着 DOM 的变化而变化),而不是一个静态数组。

Array要在真实对象中制作副本,请使用Array.from(document.getElementsByClassName(...)).

对于#2,问题似乎不在您发布的代码范围内。请发布重现该问题的代码。请注意,如果您只想为集合的每个元素做某事,则不建议.map使用虽然有效,但不建议使用。

let immigrationEvent = () => {
  const elts = Array.from(document.getElementsByClassName("hideme"));
  const [visibleElt] = elts.splice(0, 1);

  elts.map((elt) => elt.style.display = 'none');
  visibleElt.style.display = 'block';
}

document.querySelector("button").addEventListener('click', immigrationEvent, false);
<div class="hideme">one</div>
<div class="hideme">two</div>
<div class="hideme">three</div>

<button>Run</button>


推荐阅读