我正在构建一个应用程序,我需要从标题中删除具有特定类的所有链接元素。我已经建立了一个在w3schools编辑器中遇到的问题的示例。
出于重现问题的目的,我在标题中添加了多个相同的链接,并添加了“ link-to-remove”类:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" class="link-to-remove">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" class="link-to-remove">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" class="link-to-remove">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" class="link-to-remove">
这是我用来删除链接的功能:
function removeLinks() {
const head = document.getElementsByTagName('head')[0];
const links = head.getElementsByClassName('link-to-remove');
for(let i = 0; i < links.length; i++) {
head.removeChild(links[i]);
}
}
该函数具有删除所有链接元素的逻辑,但每次仅删除少数几个。只有多次按下触发该功能的按钮后,所有链接才会被删除。 (在示例中,当引导表格样式消失时,所有链接都被删除)
示例: https://www.w3schools.com/code/tryit.asp?filename=G36L0TRX06V3
我需要在此功能中进行哪些更改,使其在首次触发时删除所有链接?
答案 0 :(得分:7)
问题是getElementsByClassName
返回一个 live HTMLCollection
-如果在迭代过程中从其中删除一个元素,则该集合将在更改时更改。例如:
const foos = document.getElementsByClassName('foo');
console.log(foos[1].textContent);
foos[0].remove();
console.log(foos[1].textContent);
<div class="foo">a</div>
<div class="foo">b</div>
<div class="foo">c</div>
这很不直观。要么向后遍历整个集合(例如,从length - 1
到length - 2
,... 0
),以确保遍历每个元素,或者使用querySelectorAll
,返回 static NodeList
:
const links = head.querySelectorAll('.link-to-remove');
querySelectorAll
的另一个好处是,较新的浏览器在NodeLists上支持forEach
,因此您可以直接对其进行迭代,而不必使用难看的for
循环:
document.querySelectorAll('head .link-to-remove').forEach((removeMe) => {
removeMe.remove();
});
(如您所见,如果将head
放入传递给head
的查询字符串中,则无需选择querySelectorAll
-您也可以remove()
元素,而不必引用其父元素并使用removeChild
)
答案 1 :(得分:3)
当您从DOM中删除元素时,getElementsByTagName
方法将返回一个实时HTML元素集合,该元素将被更新,因此由于该元素的索引正在更改,它将跳过某些元素。
要使其使用保留集合长度并向后迭代的变量起作用。
function removeLinks() {
const head = document.getElementsByTagName('head')[0];
const links = head.getElementsByClassName('link-to-remove');
let i = links.length;
while(i--) {
head.removeChild(links[i]);
}
}
或者,您也可以使用forEach
function removeLinks() {
const head = document.getElementsByTagName('head')[0];
const links = head.getElementsByClassName('link-to-remove');
links.forEach(el => el.remove())
}
使用querySelectorAll
,forEach
和remove
方法更简单。
function removeLinks() {
document.querySelectorAll('head .link-to-remove').forEach(el => el.remove())
}
答案 2 :(得分:1)
您必须将样式表设置为禁用,因为它会将css样式保留在内存中,因此删除该元素将不起作用,如果我没有记错的话,在某些情况下它也可能导致其崩溃。
function removeLinks() {
const head = document.getElementsByTagName('head')[0];
const links = head.getElementsByClassName('link-to-remove');
for(let i = 0; i < links.length; i++) {
links[i].disabled = true;
}
}
例如:document.styleSheets[0].disabled = true;
jQuery方式=> $('link[title=mystyle]')[0].disabled=true;
答案 3 :(得分:0)
<link>s
。 .getElementsByClassName()
, .getElementsByTagName()
和 .getElementsByName()
等较旧的方法是 Live HTMLCollections < / strong>(类似数组的对象),因此.length
会在每次迭代时更新,它会减少循环并过早地结束循环。您可以通过禁用每个<link>
而不是删除它们(不要触摸.length
)来实现目标,或使用返回静态 NodeList (数组为像对象)一样更通用的 .querySelectorAll()
方法。另一种方法是通过 Array.from()
此演示将类似数组的对象转换为数组:
显示了两个不同的接口来处理<link>
第一个使用 CSSStyleSheet 界面的styleSheet
对象
<link>s
.querySelectorAll()
的DOM的第二个 HTMLLinkElement 接口
单击红色按钮以删除目标<link>s
注意:是一个实时HTML集合,因此在删除link.link-to-remove
时可以在控制台中对其进行准确计数。
要正确测试每个示例,请重新运行演示,然后单击另一个按钮。
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" class="link-to-remove">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" class="link-to-remove">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" class="link-to-remove">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" class="link-to-remove">
</head>
<body>
<button class='btn btn-warning'>CLICK TO DISABLE ALL STYLESHEETS</button>
<a href='#/' class='btn btn-danger'>REMOVE ALL <code>link.link-to-remove</code></a>
<script>
// Collect all stylesheets and convert to an array
let sheets = Array.from(document.styleSheets);
console.log('=========STYLESHEET QTY===========');
// Test: Check how many stylesheets there are
console.log('This page has ' + sheets.length + ' stylesheets');
console.log('=============All HREF=============');
// Test: View each stylesheet href
for (let sheet of sheets) {
console.log(sheet.href);
}
document.querySelector('button').onclick = function(e) {
// Start disabling all stylesheets beginning at the 3rd position
for (let s = 0; s < sheets.length; s++) {
if (s >= 2) {
sheets[s].disabled = true;
}
}
console.log('=============DISABLED=============');
// Test: See which stylesheets were disabled
for (let sheet of sheets) {
console.log(sheet.disabled);
}
}
let nodeList = document.querySelectorAll('.link-to-remove');
let htmlCol = document.getElementsByClassName('link-to-remove');
document.querySelector('a').onclick = function(e) {
nodeList.forEach(link => link.remove());
console.log('=========STYLESHEET QTY===========');
// Test: Check how many stylesheets there are
console.log('This page has ' + htmlCol.length + ' stylesheets with the className: .link-to-remove');
console.log('=============All CLASS=============');
// Test: View each all link.class
for (let tag of htmlCol) {
console.log(tag.className);
}
}
</script>
</body>
</html>