我创建了创建元素的函数
function createElements(value) {
//Create div .toggler
const toggler = document.createElement('div');
toggler.classList.add('toggler');
//Create div .content
const content = document.createElement('div');
content.classList.add('content');
//Append div .toggler in div .container
container.append(toggler);
//Append div .content in div .container
container.append(content);
toggler.innerText = 'Click me';
content.innerText = value;
}
如果我单击切换器“单击我”,则应显示和隐藏内容的函数
function toggleContent() {
//Get created elements
const togglers = document.querySelectorAll('.toggler'),
contents = document.querySelectorAll('.content');
//Toggle both div .active
togglers.forEach((toggler, index) => {
const content = contents[index];
//Get div .content height
const contentHeight = content.clientHeight + 'px';
//Set div .content height
content.style.height = '0px';
//Toggle event
toggler.addEventListener('click', () => {
if (!toggler.classList.contains('active')) {
toggler.classList.add('active');
} else {
toggler.classList.remove('active');
}
if (!content.classList.contains('active')) {
content.classList.add('active');
content.style.height = contentHeight;
} else {
content.classList.remove('active');
content.style.height = '0px';
}
});
});
}
将这两个函数放在按钮事件中
//Create html elements and set value inner them event
btn.addEventListener('click', () => {
createElements(input.value);
toggleContent();
//Clear input value
input.value = '';
// console.log(input.value);
});
一切正常,但如果我添加第二个元素,第一个元素切换器将不起作用
//Get html elements
const container = document.querySelector('.container'),
input = document.querySelector('.input'),
btn = document.querySelector('.btn');
function createElements(value) {
//Create div .toggler
const toggler = document.createElement('div');
toggler.classList.add('toggler');
//Create div .content
const content = document.createElement('div');
content.classList.add('content');
//Append div .toggler in div .container
container.append(toggler);
//Append div .content in div .container
container.append(content);
toggler.innerText = 'Click me';
content.innerText = value;
}
function toggleContent() {
//Get created elements
const togglers = document.querySelectorAll('.toggler'),
contents = document.querySelectorAll('.content');
//Toggle both div .active
togglers.forEach((toggler, index) => {
const content = contents[index];
//Get div .content height
const contentHeight = content.clientHeight + 'px';
//Set div .content height
content.style.height = '0px';
//Toggle event
toggler.addEventListener('click', () => {
if (!toggler.classList.contains('active')) {
toggler.classList.add('active');
} else {
toggler.classList.remove('active');
}
if (!content.classList.contains('active')) {
content.classList.add('active');
content.style.height = contentHeight;
} else {
content.classList.remove('active');
content.style.height = '0px';
}
});
});
}
//Create html elements and set value inner them event
btn.addEventListener('click', () => {
createElements(input.value);
toggleContent();
//Clear input value
input.value = '';
// console.log(input.value);
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.content {
overflow: hidden;
}
<input type="text" class="input" />
<button class="btn">add</button>
<div class="container">
<!-- <div class="toggler"></div>
<div class="content"></div> -->
</div>
最佳答案
第一个切换器(以及添加更多元素后的后续切换器)由于以下两个原因而停止工作:
- 每次添加新元素时,都会向现有元素添加另一个点击监听器(因此,当添加第二个元素时,第一个元素会获得另一个点击监听器,这会导致稍后出现一些奇怪的情况)
- 每次为每个现有项目添加新元素时,您都会记住它们的
clientHeight
,因此如果它们实际上处于折叠状态,您会将0px
存储到contentHeight
因此新的点击处理程序将始终使用0px
来扩展状态高度。最好切换display: none
和display: block
(或者根据需要选择 inline 或 inline-block)
我将点击处理程序注册移至第一个函数,这样每个创建的元素仅获得一个点击处理程序。
我删除了 clientHeight/contentHeight 逻辑,只添加了一个 CSS 规则,以便 .content
项在 .active
时可见,否则不可见。
所以改变的是CSS中的这部分
.content {
display: none;
}
.content.active {
display: block;
}
我保留了这样的逻辑:当您添加新项目时,它将折叠所有现有项目。我认为这也是你的逻辑,但如果你不想要这样,请告诉我。
更改是在 JS 代码中
//Toggle both div .active
togglers.forEach((toggler, index) => {
const content = contents[index];
// I added this to keep the same logic you had before
// if you would like to not collapse them, just remove the 2 lines
toggler.classList.remove('active');
content.classList.remove('active');
});
//Get html elements
const container = document.querySelector('.container'),
input = document.querySelector('.input'),
btn = document.querySelector('.btn');
function createElements(value) {
//Create div .toggler
const toggler = document.createElement('div');
toggler.classList.add('toggler');
//Create div .content
const content = document.createElement('div');
content.classList.add('content');
//Append div .toggler in div .container
container.append(toggler);
//Append div .content in div .container
container.append(content);
toggler.innerText = 'Click me';
content.innerText = value;
toggler.addEventListener('click', () => {
if (!toggler.classList.contains('active')) {
toggler.classList.add('active');
} else {
toggler.classList.remove('active');
}
if (!content.classList.contains('active')) {
content.classList.add('active');
} else {
content.classList.remove('active');
}
});
}
function toggleContent() {
//Get created elements
const togglers = document.querySelectorAll('.toggler'),
contents = document.querySelectorAll('.content');
//Toggle both div .active
togglers.forEach((toggler, index) => {
const content = contents[index];
toggler.classList.remove('active');
content.classList.remove('active');
});
}
//Create html elements and set value inner them event
btn.addEventListener('click', () => {
createElements(input.value);
toggleContent();
//Clear input value
input.value = '';
// console.log(input.value);
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.content {
display: none;
}
.content.active {
display: block;
}
<input type="text" class="input" />
<button class="btn">add</button>
<div class="container">
<!-- <div class="toggler"></div>
<div class="content"></div> -->
</div>
关于javascript - 添加第二个元素后,第一个元素不会切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70645958/