用js的getSelection()實現型別電子書閱讀器的劃詞文字高亮選中功能
阿新 • • 發佈:2021-01-16
技術標籤:js
這裡只是一個demo幫助理解文字高亮選中的實現原理,還有多段選中,重複選中等功能沒有實現,如果想用現成的產品可以參考一位大佬的部落格https://segmentfault.com/a/1190000018981813
<!DOCTYPE html>
<html lang="cmn">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#app {
position: relative;
}
.red {
border-bottom: 2px solid red;
}
.box {
position: absolute;
left: 0;
top: 0;
width: 150px;
height: 50px;
background : pink;
}
.green {
border-bottom: 2px solid green;
}
</style>
</head>
<body>
<div id="app">
<p>
這是一段文字要實現選中高亮這是一段文字要實現選中高亮這是一段文字要實現選中高亮這是一段文字要實現選中高亮
這是一段文字要實現選中高亮這是一段文字要實現選中高亮這是一段文字要實現選中高亮這是一段文字要實現選中高亮
這是一段文字要實現選中高亮這是一段文字要實現選中高亮這是一段文字要實現選中高亮
這是一段文字要實現選中高亮這是一段文字要實現選中高亮這是一段文字要實現選中高亮
這是一段文字要實現選中高亮這是一段文字要實現選中高亮
這是一段文字要實現選中高亮這是一段文字要實現選中高亮這是一段文字要實現選中高亮這是一段文字要實現選中高亮
</ p>
<div class="box" v-show="showBox" :style="styleBox">
<button @click="createSpan('red')">紅線</button>
<button @click="createSpan('green')">綠線</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {
showBox: false,
styleBox: {
left: 0,
top: 0
},
selectNode: null
};
},
created() {
this.init();
},
methods: {
init() {
const that = this;
document.addEventListener("mouseup", function (e) {
if (window.getSelection().rangeCount === 0 || that.showBox) {
return false;
}
// 獲取選中
const range = window.getSelection().getRangeAt(0);
const comNode = range.commonAncestorContainer;
const start = {
node: range.startContainer,
offset: range.startOffset
};
const end = {
node: range.startContainer,
offset: range.endOffset
};
// 最簡單的一種情況一行選中
if (start.offset !== end.offset) {
// 以開始選中位置切割一分為2的後半部分
const lastText = start.node.splitText(start.offset);
// 以後半部分按照開始選中到結束選中的偏移量切割,並選擇前一部分
const selected = lastText.splitText(end.offset - start.offset)
.previousSibling;
that.selectedNode = selected;
that.styleBox = {
left: e.clientX - 16 + "px",
top: e.clientY + "px"
};
that.showBox = true;
}
});
},
createSpan(color) {
// 建立一個span來包裹,並新增樣式
const span = document.createElement("span");
span.setAttribute("class", color);
span.appendChild(this.selectedNode.cloneNode(false));
this.selectedNode.parentNode.replaceChild(span, this.selectedNode);
this.showBox = false;
}
}
});
</script>
</body>
</html>