在js
当中,创建一个元素需要使用createElement()
函数,那么克隆一个元素又没有比较直接的方法呢
克隆一个元素使用的是cloneNode()
具体示例
原生js实现
在原生js
当中克隆元素使用的是cloneNode(参数),
参数为true
标识克隆元素及其所有子元素,如果为false
则标识只克隆元素但不包含它的子节点,不过在绝大多数情况下,我们都是希望复制所有的子节点,所以,一般都是使用true
参数
// 克隆元素
function cloneImg() {
// 获取元素DOM
var myImg = document.getElementById("myImg");
// 克隆出新的元素
var newImg = myImg.cloneNode(true);
// 使用appendChild()函数挂载到指定的DOM中
document.querySelector('.myContent').appendChild(newIMg);
}
如下是Html
模板代码
<p class="myContent">
<input type="button" value="克隆" onclick="cloneImg()" /><br />
<!--定义图片要克隆的元素--->
<img id="myImg" src="xxxx.jpg" width="100" height="200" />
</p>
分析
克隆一个元素使用的是cloneNode()
方法,想要复制哪个DOM
对象,那么直接在这个对象下面直接使用这个cloneNode()
方法就好
Vue示例实现
下面的代码是上面演示的示例完整源码
<template>
<div class="wrap">
<div>
<el-button type="primary" @click="handleClone">克隆</el-button>
</div>
<div class="img-content">
<div class="myImg">
<img class="img" src="https://img1.baidu.com/it/u=829829583,2565413602&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=661" width="150" height="100" ></img>
<img class="closeimg" @click="handleDelete" src="https://img0.baidu.com/it/u=3387898836,1597995708&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666026000&t=e8de3885ef1563b4f8806bc4fcc3507b" width="25" height="25" >
</div>
</div>
</div>
</template>
<script>
export default {
name: 'cloneNodeElem',
data() {
return {
handleClone() {
let myImg = document.querySelector(".myImg");
if(myImg) {
// 克隆出新的元素
var newImg = myImg.cloneNode(true);
// 克隆节点,只会克隆元素,但新的节点不会将事件也复制进来,所以针对新添加的元素需要添加事件函数
// 标准浏览器是不复制事件的,防止循环引用无法释放内存。 IE使用attachEvent添加的事件可以复制,直接dom.onclick也无法复制。 重新给克隆的对象添加事件来解决
newImg.children[1].addEventListener('click',(event) => {
console.log(event);
let myImg = event.currentTarget.parentElement;
let imgContent = myImg.parentElement;
imgContent.removeChild(myImg);
})
// 使用appendChild()函数进行挂载
document.querySelector(".img-content").appendChild(newImg);
} else {
alert('元素节点不存在,无法克隆新元素,请刷新页面,然后对原有的元素进行克隆');
location.reload()
}
},
handleDelete(elem){
console.log(elem);
// 通过事件对象,cuurentTarget目标元素,parentElement找到父级元素,此时找到的是myImg元素
let myImg = elem.currentTarget.parentElement;
console.log(myImg);
// 在次通过parentElement找到muImg的父级元素,也就是imgContent
let imgContent = myImg.parentElement;
console.log(imgContent)
// 通过removeChild()方法,删除对应的子元素
imgContent.removeChild(myImg);
}
}
}
}
</script>
<style lang="scss" scoped>
.wrap {
text-align: center;
}
.img-content {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.img-content .myImg {
position:relative;
}
.img-content .myImg .img {
margin-left: 10px;
margin-top: 10px;
}
.closeimg {
position:absolute;
right: 5px;
top: 17px;
cursor:pointer;
}
</style>
注意事项
使用cloneNode()复制元素节点,只会复制元素,并不会将原有元素绑定的事件也一并复制过来,所以在复制原有元素的节点后,需要对新的元素
指定的目标元素绑定事件,不然的话,新创建的元素是没有任何事件绑定,是不会触发的,只有原始的元素绑定的事件才会有效
另外需要注意的是,在vue当中获取子元素的父节点,跟原生js的获取父节点parentNode有点不一样
它使用的是事件对象参数.currentTarget.parentElement
这种方式获取子元素的父级节点的
其他的,与原生js删除一个节点,使用removeChild()
都没有什么区别
上面的示例代码中,在克隆元素前做了一个条件判断,判断有没有子元素存在,因为当没有子元素存在时,对于一个页面中不存在的元素,是没办法实现克隆的
实现克隆的基础,是原DOM对象元素必须是存在页面中的,才可以实现克隆
上面的示例代码只是为了一个演示这个cloneNode()
API的使用,在原生js和在Vue当中如何使用,以及如何删除一个节点
在实际开发中,如果使用的是Vue框架,并不会像项目那样,去操作DOM,一般都是把数据存放到一个数组对象当中,结合复制的接口,然后操作数组对象,去克隆数据的
光在前台实现静态的数据克隆的复制,也没有啥意义,实际开发中,克隆复制,是要拷贝到数据库当中去的,所以实现这个克隆操作,是需要后台提供具体的接口支持的