JS报错:Uncaught DOMException:Failed to execute ‘removeChild’ on ‘Node’: The node to be removed is not a child of this node
最近在练习js项目,使用addEventListener做事件嵌套的时候采坑了。做的是商品放大镜的效果,有三个事件,鼠标移入(mouseenter)时创建蒙版(maskDiv),鼠标移动(mousemove)时蒙版跟随鼠标移动,鼠标移出(mouseleave)时移除蒙版。因为刚开始将创建蒙版放在了mouseenter事件里,mouseenter和mouseleave事件中都需要对蒙版进行操作,所以将mouseenter和mouseleave放在了mouseenter中嵌套使用。
原代码如下:
//2.设置移入事件
smallPic.addEventListener('mouseenter', () => {
// 3.创建蒙版元素
const maskDiv = document.createElement('div')
maskDiv.className = 'mask'
// 4.创建大图框元素
const bigPic = document.createElement('div')
bigPic.id = 'bigPic'
// 5.创建大图片元素
const bigImg = document.createElement('img')
bigImg.src = imagessrc[bigimgIndex].b
// 6.大图框来追加大图片
bigPic.appendChild(bigImg)
// 7.小图框追加蒙版元素
smallPic.appendChild(maskDiv)
// 8.leftTop追加大图框元素
leftTop.appendChild(bigPic)
// 设置移动事件
smallPic.addEventListener('mousemove', function (e) {
//e.clientX: 鼠标点距离浏览器左侧X轴的值
//getBoundingClientRect().left:小图框元素距离浏览器左侧可视left值
//offsetWidth:为元素的占位宽度
let left = e.clientX - smallPic.getBoundingClientRect().left - maskDiv.offsetWidth / 2
let top = e.clientY - smallPic.getBoundingClientRect().top - maskDiv.offsetHeight / 2
// 蒙版元素边界控制
// smallPic.clientWidth为小图框的可视宽度
// left大于小图框的可视宽度-蒙版的占位宽度时,蒙版就会超出小图框
if (left < 0) {
left = 0
} else if (left > smallPic.clientWidth - maskDiv.offsetWidth) {
left = smallPic.clientWidth - maskDiv.offsetWidth
}
if (top < 0) {
top = 0
} else if (top > smallPic.clientHeight - maskDiv.offsetHeight) {
top = smallPic.clientHeight - maskDiv.offsetHeigh
}
// 设置蒙版的left和top
maskDiv.style.left = left + 'px'
maskDiv.style.top = top + 'px'
// 大图框里的大图片和蒙版等比例移动
// 移动的比例关系 = 蒙版元素移动的距离 / 大图片元素移动的距离
//蒙版元素移动的距离 = 小图框宽度 – 蒙版元素的宽度
//大图片元素移动的距离 = 大图片宽度 – 大图框元素的宽度
const scale = (smallPic.clientWidth - maskDiv.offsetWidth) / (bigImg.offsetWidth - bigPic.clientWidth)
bigImg.style.left = -left / scale + 'px'
bigImg.style.top = -top / scale + 'px'
})
// 设置移出事件
smallPic.addEventListener('mouseleave', () => {
// 小图框移除蒙版元素
smallPic.removeChild(maskDiv)
// leftTop移除大图框
leftTop.removeChild(bigPic)
})
})
将mouseenter和mouseleave从mouseenter中拿出来后报错解除
修改后的代码:
// 3.创建蒙版元素
const maskDiv = document.createElement('div')
maskDiv.className = 'mask'
// 4.创建大图框元素
const bigPic = document.createElement('div')
bigPic.id = 'bigPic'
// 5.创建大图片元素
const bigImg = document.createElement('img')
bigImg.src = imagessrc[bigimgIndex].b
// 6.大图框来追加大图片
bigPic.appendChild(bigImg)
// 设置移入事件
smallPic.addEventListener('mouseenter', () => {
// 7.小图框追加蒙版元素
smallPic.appendChild(maskDiv)
// 8.leftTop追加大图框元素
leftTop.appendChild(bigPic)
})
// 设置移动事件
smallPic.addEventListener('mousemove', function (e) {
//e.clientX: 鼠标点距离浏览器左侧X轴的值
//getBoundingClientRect().left:小图框元素距离浏览器左侧可视left值
//offsetWidth:为元素的占位宽度
let left = e.clientX - smallPic.getBoundingClientRect().left - maskDiv.offsetWidth / 2
let top = e.clientY - smallPic.getBoundingClientRect().top - maskDiv.offsetHeight / 2
// 蒙版元素边界控制
// smallPic.clientWidth为小图框的可视宽度
// left大于小图框的可视宽度-蒙版的占位宽度时,蒙版就会超出小图框
if (left < 0) {
left = 0
} else if (left > smallPic.clientWidth - maskDiv.offsetWidth) {
left = smallPic.clientWidth - maskDiv.offsetWidth
}
if (top < 0) {
top = 0
} else if (top > smallPic.clientHeight - maskDiv.offsetHeight) {
top = smallPic.clientHeight - maskDiv.offsetHeigh
}
// 设置蒙版的left和top
maskDiv.style.left = left + 'px'
maskDiv.style.top = top + 'px'
// 大图框里的大图片和蒙版等比例移动
// 移动的比例关系 = 蒙版元素移动的距离 / 大图片元素移动的距离
//蒙版元素移动的距离 = 小图框宽度 – 蒙版元素的宽度
//大图片元素移动的距离 = 大图片宽度 – 大图框元素的宽度
const scale = (smallPic.clientWidth - maskDiv.offsetWidth) / (bigImg.offsetWidth - bigPic.clientWidth)
bigImg.style.left = -left / scale + 'px'
bigImg.style.top = -top / scale + 'px'
})
// 设置移出事件
smallPic.addEventListener('mouseleave', () => {
// 小图框移除蒙版元素
smallPic.removeChild(maskDiv)
// leftTop移除大图框
leftTop.removeChild(bigPic)
})
是因为用addEventListener做事件嵌套会有冲突吗?还是没搞懂报错的原因,试了下用传统的on来注册事件再进行这样的事件嵌套时是不会报错的。有没有大佬可以帮忙解答一下。。。