一个效果图,一段代码, 就这样吧。
html
<template>
<!-- <el-checkbox v-model="">开启双向</el-checkbox> -->
<div
ref="checkListRef"
@mouseup="mouseupCon"
@mousedown="mousedownCon"
@mouseover="mouseoverCon"
@mouseout="mouseoutCon"
>
<el-checkbox-group v-model="checkedList" class="user-select-auto">
<el-checkbox
v-for="(item, i) in checkArr"
:key="item.id"
:label="item.value"
class="m-4"
:data-index="i"
@mouseover.native="mouseoverItem"
></el-checkbox>
</el-checkbox-group>
</div>
</template>
<script>
const checkArr = new Array(200).fill(null).map((_, i) => {
return {
id: i,
value: i,
lable: i,
checked: false,
}
})
export default {
data() {
return {
checkArr,
checkedList: [],
isOver: false, // 是否在容器
isDown: false, // 是否在容器按下状态
}
},
methods: {
mousedownCon(val) {
// console.log('mousedownCon', val)
this.isDown = true
},
mouseupCon(val) {
// console.log('mouseupCon', val)
if (this.isDown === false || this.isOver === false) {
return
}
const sel = window.getSelection()
console.log(sel)
const { anchorNode, extentNode } = sel
if (!anchorNode || !extentNode) {
return
}
const { startIndex, endIndex } = this.getSEIndex(anchorNode, extentNode)
this.setChecked(startIndex, endIndex)
console.log(startIndex, endIndex)
this.isDown = false
window.getSelection().removeAllRanges()
},
getSEIndex(anchorNode, extentNode) {
let startDom = anchorNode
let endDom = extentNode
if (extentNode.classList && extentNode.classList.contains('el-checkbox__input')) {
endDom = extentNode.parentElement
} else if (extentNode.nodeName === '#text') {
endDom = extentNode.parentElement.parentElement
}
if (anchorNode.classList && anchorNode.classList.contains('el-checkbox__input')) {
startDom = anchorNode.parentElement
} else if (anchorNode.nodeName === '#text') {
startDom = anchorNode.parentElement.parentElement
}
let startIndex = Number(startDom.dataset.index)
let endIndex = Number(endDom.dataset.index)
if (parseInt(startIndex) > parseInt(endIndex)) {
const temp = endIndex
endIndex = startIndex
startIndex = temp
}
return { startIndex, endIndex }
},
setChecked(startIndex, endIndex) {
for (let i = startIndex; i < endIndex + 1; i++) {
const ind = this.checkedList.findIndex(x => {
return this.checkArr[i].id === x
})
if (ind > -1) {
this.checkedList.splice(ind, 1)
} else {
this.checkedList.push(this.checkArr[i].id)
}
}
},
mouseoutCon(val) {
// console.log('mouseoutCon', val)
this.isOver = false
},
mouseoverCon() {
this.isOver = true
},
mouseoverItem(val) {
// this.isOver = true
// console.log('mouseoverItem', val)
// const sel = window.getSelection()
// console.log(sel)
},
},
}
</script>
<style lang="less">
.el-checkbox {
user-select: auto;
}
.user-select-none {
user-select: none;
}
.user-select-auto {
user-select: auto;
}
.el-checkbox__input {
user-select: none;
}
.el-checkbox-group::selection {
background-color: #fff;
color: #206ef7;
}
.el-checkbox__label::selection {
background: #fff;
color: #206ef7;
}
</style>