HTML + Javascript:不能一次从两个元素中获取所有实例?
Posted
技术标签:
【中文标题】HTML + Javascript:不能一次从两个元素中获取所有实例?【英文标题】:HTML + Javascript: can't get all instances from two elements at once? 【发布时间】:2021-11-19 03:47:45 【问题描述】:我想为一组选择性元素的所有实例添加一个 CSS 样式类:例如,所有 p 元素以及所有 h4 元素。 p>
我定义了两个 JS 变量,它们获取上述标签的所有元素,并将它们插入到一个数组中,这样我就可以创建一个函数,理论上,应该将所选类应用于所选元素/标签的所有实例.
但是,当我运行代码时,该函数似乎只将类分配给数组的第一项。
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.italic font-style: italic;
</style>
</head>
<body>
<h4>Text goes in here</h4>
<p>Text goes in here</p>
<script>
function styleTxt()
let h4Elems = document.getElementsByTagName("H4");
let pElems = document.getElementsByTagName("P");
const elemArray = [pElems, h4Elems];
for (eachElem in elemArray)
let elemInsts = elemArray[eachElem];
for (eachInst in elemInsts)
let givenInst = elemInsts[eachInst];
givenInst.classList.add("italic");
styleTxt();
</script>
</body>
</html>
如果我颠倒数组中元素标签的顺序,则 h4 元素将获得 .italic 类,但 p元素不会。
也许不能两次使用“document”指令?是否有另一种方法可以将同一类自动添加到一组多个(但不是全部)html标签中?
【问题讨论】:
您应该检查浏览器控制台是否有错误。 【参考方案1】:您正在遍历 HTMLCollection 的每个属性,包括像 length
这样的属性,导致 givenInst
成为一个数字。由于它没有classList
属性,因此在undefined
上调用add
会产生错误并终止循环。
为了解决这个问题,你可以使用isNaN
来检查属性是否为数字:
.italic
font-style: italics;
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.italic
font-style: italic;
</style>
</head>
<body>
<h4>Text goes in here</h4>
<p>Text goes in here</p>
<script>
function styleTxt()
let h4Elems = document.getElementsByTagName("H4");
let pElems = document.getElementsByTagName("P");
const elemArray = [pElems, h4Elems];
for (eachElem in elemArray)
let elemInsts = elemArray[eachElem];
for (eachInst in elemInsts)
if (!isNaN(eachInst))
let givenInst = elemInsts[eachInst];
givenInst.classList.add("italic");
styleTxt();
</script>
</body>
</html>
但是,更好的方法是使用 for...of
循环:
.italic
font-style: italics;
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.italic
font-style: italic;
</style>
</head>
<body>
<h4>Text goes in here</h4>
<p>Text goes in here</p>
<script>
function styleTxt()
let h4Elems = document.getElementsByTagName("H4");
let pElems = document.getElementsByTagName("P");
const elemArray = [pElems, h4Elems];
for (eachElem of elemArray)
for (eachInst of eachElem)
eachInst.classList.add("italic");
styleTxt();
</script>
</body>
</html>
【讨论】:
您的第二个选择对我来说非常有效!我应该更多地了解 for...in 和 for...of 循环之间的区别;也许 for...of 循环是未来。【参考方案2】:试试这个
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.italic
font-style: italic;
</style>
</head>
<body>
<h4>Text goes in here</h4>
<p>Text goes in here</p>
<script>
function styleTxt()
const h4Elems = Array.from(document.getElementsByTagName("H4"));
const pElems = Array.from(document.getElementsByTagName("P"));
const elemArray = [...pElems, ...h4Elems];
elemArray.forEach(eachElem =>
eachElem.classList.add("italic");
)
styleTxt();
</script>
</body>
</html>
【讨论】:
【参考方案3】:使用Document.querySelectorAll()
获取这两种类型的元素。用NodeList.forEach()
迭代NodeList
,并将类添加到每个元素。
function styleTxt()
document.querySelectorAll('h4, p')
.forEach(el => el.classList.add('italic'));
styleTxt();
.italic
font-style: italic;
<h4>Text goes in here</h4>
<p>Text goes in here</p>
【讨论】:
【参考方案4】:您可能更喜欢for...of 循环并使用spread operator。它将产生更好的代码输出:
function styleTxt()
const h4Elems = document.getElementsByTagName("H4");
const pElems = document.getElementsByTagName("P");
const elemArray = [...pElems, ...h4Elems];
for (const eachElem of elemArray)
eachElem.classList.add("italic");
当然,您始终可以使用querySelectorAll
方法一次性选择两种类型的元素:
const all = document.querySelectorAll("h4, p");
// Using the for...of loop:
for ( const el of all )
el.classList.add("italic");
// Using the `forEach` method:
all.forEach( el => el.classList.add("italic") )
【讨论】:
感谢您的两种方法。我渴望成为一名 Web 开发人员,但我仍处于业余水平,因此还不熟悉 lambda 表达式。无论如何,我知道了 for...of 循环和扩展运算符,这些我都不知道。圣体圣事! 在这种情况下,我会更好地重构我的代码以包含最佳实践:只要变量的值没有改变,就使用 const。 Добро пожаловать! :)以上是关于HTML + Javascript:不能一次从两个元素中获取所有实例?的主要内容,如果未能解决你的问题,请参考以下文章
一次从一个 TCP 套接字发送超过 32768 个字节到另一个
ef core 如何一次从具有外键的不同表中获取数据? (数据库优先)