<div class="form-group p-3">
<label>Content</label>
<div contenteditable="true" class="form-control h-auto">
<p>每个人还是要坚持自己独立的思想,因为要有人站出来说真话,必须要有人,这个世界必须要有不同的声音。</p>
<style>
test {}
</style>
<p>早知道有今天,我管他批评不批评,『老子』到处说!</p>
</div>
<small class="form-text text-muted">
Put text above, and select some words, it'll be spoken out automatically.
</small>
</div>
const voice = speechSynthesis
.getVoices()
.find(({ lang }) => lang === navigator.language);
function speak(text) {
const content = new SpeechSynthesisUtterance(text);
content.voice = voice;
speechSynthesis.speak(content);
}
function* walkRange(range) {
const walker = document.createNodeIterator(range.commonAncestorContainer);
var current;
while ((current = walker.nextNode())) {
if (range.intersectsNode(current)) yield current;
if (current === range.endContainer) break;
}
}
function getSelectedText(box) {
const range = self.getSelection()?.getRangeAt(0);
if (
range &&
range + "" &&
(!box || box.contains(range.commonAncestorContainer))
)
return [walkRange(range)]
.filter(({ nodeType, parentNode }) => {
if (nodeType !== 3) return;
const { width, height } = parentNode.getBoundingClientRect();
return width && height;
})
.map(({ nodeValue }, index, { length }) =>
nodeValue.slice(
index === 0 ? range.startOffset : 0,
index === length - 1 ? range.endOffset : Infinity
)
)
.filter((text) => text.trim())
.join("")
.trim();
}
const input = document.querySelector('[contenteditable="true"]');
document.addEventListener("selectionchange", () => {
const text = getSelectedText(input);
if (text && !speechSynthesis.speaking) speak(text);
else speechSynthesis.cancel();
});
View Compiled
This Pen doesn't use any external JavaScript resources.