为何给slides生成点按钮时,insertAdjacentElement仅生成1个而insertAdjacentHTML生成4个?
问题描述
我想为slides这个NodeList里的每张图片生成一个点按钮,slides实际包含4张图片,但用insertAdjacentElement方法时只生成1个点按钮,代码如下:
const dotContainer = document.querySelector('.dots'); const slides = document.querySelectorAll('.slide'); const slider = document.querySelector('.slider'); // images are name slides! const createDots = function () { const dot = document.createElement('button'); dot.classList.add('dots__dot'); slides.forEach((s, i) => { dotContainer.insertAdjacentElement('beforeend', dot); }); const dots = document.querySelectorAll('.dots__dot'); dots.forEach((d, i) => (d.dataset.slide = `${i}`)); }; createDots();
控制台打印显示slides是包含4个元素的NodeList,但仅生成1个点按钮。改用insertAdjacentHTML方法则正常生成4个点按钮,代码如下:
const createDots = function () { const dot = document.createElement('button'); dot.classList.add('dots__dot'); slides.forEach((s, i) => { // dotContainer.insertAdjacentElement('beforeend', dot); dotContainer.insertAdjacentHTML( 'beforeend', `<button class="dots__dot" data-slide="0"></button>` ); }); const dots = document.querySelectorAll('.dots__dot'); dots.forEach((d, i) => (d.dataset.slide = `${i}`)); }; createDots();
请问这是什么原因?
原因分析
- 核心问题是DOM元素的唯一性:你在循环外只创建了一个
dot元素对象,每次调用insertAdjacentElement时,并不是复制这个元素,而是把同一个元素从当前位置(第一次插入后就在容器里)移动到容器的末尾。循环执行4次,本质上只是把同一个按钮移动了4次,最终容器里只会留下这一个按钮。 - 而
insertAdjacentHTML是每次循环都解析传入的HTML字符串,创建一个全新的DOM元素插入到容器中,所以4次循环会生成4个独立的按钮元素。
正确写法示例
把元素创建逻辑放到循环内部,每次生成新的按钮:
const createDots = function () { slides.forEach((s, i) => { const dot = document.createElement('button'); dot.classList.add('dots__dot'); dot.dataset.slide = `${i}`; // 直接在这里设置属性,省去后续遍历 dotContainer.insertAdjacentElement('beforeend', dot); }); }; createDots();
内容的提问来源于stack exchange,提问作者Programista Vista
相关产品推荐
相关产品推荐

