举个栗子
点击按钮只修改响应式数据,达到DOM更新和数据更新的功能
核心思想
定义一个即将被监听劫持的对象 => 给每一个对象.属性增加Object.defineProperty(),从而实现修改属性是会触发getter和setter
- getter 用于获取被劫持后计算出指定的结果
- setter 监听到修改操作时,由setter进行更新相关DOM
-
定义需要被劫持的响应式对象数据
-
对于定义的数据进行针对劫持,使用getter和setter进行对DOM的处理
-
当点击功能按钮时,只需要修改定义的响应式数据就可以
完整代码
供体验 希望大佬指点不足之处
供参考 下方注释掉的是JS原生操作DOM实现的
<html>
<head>
<title>操作DOM</title>
</head>
<style>
.context,.footer{
display: inline-block;
}
</style>
<script>
window.onload=function(){
let data = {
checkedLen:null,/**获取当前选中的数量*/
count:null,/**获取当前所有的item数量*/
checkboxAll:false,/**手动全选后勾选[全选/全不选]*/
selectAll:false,/**控制点击[全选]按钮*/
allDontChoose:true,/**控制点击[全不选]按钮*/
inverse:false,/**控制点击[反选]按钮*/
}
let items=document.getElementsByName('checkbox')
/**获取当前选中的数量*/
Object.defineProperty(data,'checkedLen',{
get:function(){
let items=document.getElementsByName('checkbox')
let len = 0
for (const item of items) {
if(item.checked) len++
}
return len
},
})
/**获取当前所有的item数量*/
Object.defineProperty(data,'count',{
get:function(){
let items=document.getElementsByName('checkbox')
return items.length
}
})
/**手动全选后勾选[全选/全不选]*/
Object.defineProperty(data,'checkboxAll',{
get:function(){
return data.checkedLen == data.count
},
set:function(newValue){
let all = document.getElementById('all')
all.checked = newValue
if((data.checkedLen == data.count) || newValue){
for (let item of items) {
item.checked = newValue
}
}
},
})
/**控制点击[全选]按钮*/
Object.defineProperty(data,'selectAll',{
get:function(){
return data.checkedLen == data.count
},
set:function(newValue){
let selectAll = document.getElementById('selectAll');
selectAll.disabled = newValue
if(newValue){
for (let item of items) {
item.checked = newValue
}
}
},
})
/**控制点击[全不选]按钮*/
Object.defineProperty(data,'allDontChoose',{
get:function(){
return data.checkedLen == null || data.checkedLen === 0
},
set:function(newValue){
let allDontChoose = document.querySelector('#allDontChoose')
allDontChoose.disabled = newValue
if(newValue){
for (let item of items) {
item.checked = !newValue
}
}
}
})
/**控制点击[反选]按钮*/
Object.defineProperty(data,'inverse',{
set:function(newValue){
for (let item of items) {
item.checked = !item.checked
}
}
})
data.allDontChoose = true
for (const item of items) {
item.onclick = function(){
data.selectAll = data.checkedLen == items.length
data.checkboxAll = data.checkedLen == items.length
data.allDontChoose = data.checkedLen == null || data.checkedLen === 0
}
}
/**全选*/
let selectAll = document.getElementById('selectAll')
selectAll.addEventListener('click',function(){
data.selectAll = true
data.checkboxAll = true
data.allDontChoose = false
})
/*全选/全不选*/
let checkboxAll = document.getElementById('all')
checkboxAll.addEventListener('click',function(){
data.selectAll = this.checked
data.checkboxAll = this.checked
data.allDontChoose = !this.checked
})
/*全不选*/
let allDontChoose = document.getElementById('allDontChoose')
allDontChoose.addEventListener('click',function(){
data.allDontChoose = true
data.selectAll = false
data.checkboxAll = false
})
/**反选*/
let inverse = document.getElementById('inverse')
inverse.addEventListener('click',function(){
data.inverse = true
if(data.checkedLen === 0 ){
data.selectAll = false
data.checkboxAll = false
data.allDontChoose = true
}else if(data.checkedLen < data.count){
data.selectAll = false
data.checkboxAll = false
}else{
data.selectAll = true
data.checkboxAll = true
data.allDontChoose = false
}
})
let submit = document.getElementById('submit')
submit.addEventListener('click',function(){
let chooseMatter = []
for (const item of items) {
if(item.checked) chooseMatter = [...chooseMatter,item.value]
}
alert(!!chooseMatter.length ? chooseMatter:'没有选择,请勾选喜欢的球')
})
}
</script>
<body>
<form style="max-width: 500px;">
<h3>JS原生使用Object.defineProperty劫持数据,实现响应式数据驱动DOM(借助VUE2.0的核心思想)</h3>
<fieldset>
<legend><label><input type="checkbox" id="all"/> 全选 / 全不选</label></legend>
<div class="context">
<label><input type="checkbox" name="checkbox" value="0" /> 篮球</label>
<label><input type="checkbox" name="checkbox" value="1" /> 足球</label>
<label><input type="checkbox" name="checkbox" value="2" /> 排球</label>
<label><input type="checkbox" name="checkbox" value="3" /> 冰球</label>
<label><input type="checkbox" name="checkbox" value="4" /> 花球</label>
</div>
<div class="footer">
<input type="button" value="全选" id="selectAll"></input>
<input type="button" value="全不选" id="allDontChoose"></input>
<input type="button" value="反选" id="inverse"></input>
<input type="button" value="提交" id="submit"></input>
</div>
</fieldset>
</form>
<script>
// window.onload = function(){
// let all = document.getElementById('all') /**全选/全不选*/
// let allCheckbox = document.getElementsByName('checkbox')
// for (const item of allCheckbox) {
// item.onclick = function(){
// if(!all.checked) all.checked = true
// for (const i of allCheckbox) {
// if(!i.checked) all.checked = false
// }
// }
// }
// all.addEventListener('click',function(){
// for (let item of allCheckbox) {
// if(item.checked != this.checked) item.checked = this.checked
// }
// })
// let selectAll = document.getElementById('selectAll')
// selectAll.addEventListener('click',function(){
// for (let item of allCheckbox) {
// if(!item.checked) item.checked = true
// }
// all.checked = true
// })
// let allDontChoose = document.getElementById('allDontChoose')
// allDontChoose.addEventListener('click',function(){
// for (let item of allCheckbox) {
// if(item.checked) item.checked = false
// }
// all.checked = false
// })
// let inverse = document.getElementById('inverse')
// inverse.addEventListener('click',function(){
// all.checked = true
// for (let item of allCheckbox) {
// item.checked = !item.checked
// if(!item.checked) all.checked = false
// }
// })
// let submit = document.getElementById('submit')
// submit.addEventListener('click',function(){
// let chooseMatter = []
// for (const item of allCheckbox) {
// if(item.checked) chooseMatter = [...chooseMatter,item.value]
// }
// console.log(chooseMatter)
// })
// }
</script>
</body>
</html>
微信扫一扫,免费
保护
车主号码隐私
的挪车码
即可到手免费
使用