I have developed an application that allows users to highlight text with different colors while reading.
For this functionality, I am utilizing the Selection API. However, I am encountering issues with the two-way binding aspect. When a user changes the color, the highlighted text does not update simultaneously.
Is there anyone who can provide assistance? http://jsfiddle.net/eywraw8t/424087/
To clarify my question, I am looking for the functionality where if a user changes the color, all previously highlighted text will also update.
Here is a step-by-step reproduction of the issue:
Default color
#ccc
Highlight some text (it's gray)
Choose another color, for example
#ff0000
(now any new highlighted text will be red, but previously highlighted text remains gray because the span is created viacreateElement
, not bound to Vue's data)
HTML:
<div id="app">
<label v-for="color in colors">
<input type="radio" v-model="currentColor" :value="color">
{{color}}
</label>
<h4>Select Text To Highlight</h4>
<p id="text" @mouseup="highlight">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatum ducimus veniam esse, nam rerum cumque repellat maiores! Explicabo laudantium, magni dignissimos impedit labore, dolores deserunt aspernatur eos quo, vero consequatur.
</p>
</div>
JS:
new Vue({
el: "#app",
data: {
currentColor:'#ccc',
colors: ["#ccc","#ff0000","#00ff00","#0000ff"],
selectedRange: null
},
methods: {
getSelectedText() {
if (window.getSelection) {
let sel = window.getSelection()
if (sel.getRangeAt && sel.rangeCount) {
this.selectedRange = sel.getRangeAt(0);
}
return window.getSelection().toString()
} else if (document.selection) {
this.selectedRange = document.selection.createRange()
return document.selection.createRange().text
}
return ''
},
surroundSelection(color) {
var span = document.createElement("span");
span.className = 'highlight'
span.style.fontWeight = "bold"
span.style.color = color
span.addEventListener("click", () => {
console.log('click');
});
if (window.getSelection) {
var sel = window.getSelection()
if (sel.rangeCount) {
var range = this.selectedRange.cloneRange()
range.surroundContents(span)
sel.removeAllRanges()
sel.addRange(range)
}
}
},
highlight(){
let text = this.getSelectedText();
if (this.selectedRange && text) {
this.surroundSelection(this.currentColor)
}
}
}
})