一种方法是有一本包含所有英语单词的完整词典。
const setOfAllEnglishWords = new Set([
"Hello",
"a",
"text",
"for",
"the",
"example"
// ... many many more
]);
const selection = "lo, a text for the example!";
const result = selection
.replace(/[^A-Za-z0-9\s]/g, "") // remove punctuation by replacing anything that is not a letter or a digit with the empty string
.split(/\s+/) // split text into words by using 1 or more whitespace as the break point
.filter(word => setOfAllEnglishWords.has(word));
console.log(result);
218632
话。平均字长为
4.5
信件和JS商店
2
218632 * (4.5 * 2) = 1967688 B = 1.967 MB
,在慢速3G连接上下载可能需要1分钟。
function getSetOfWordsOnPage() {
const walk = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT
);
const dict = new Set();
let n;
while ((n = walk.nextNode())) {
for (const word of n.textContent
.replace(/[^A-Za-z0-9\s]/g, "")
.split(/\s+/)
.map(word => word.trim())
.filter(word => !!word)) {
dict.add(word);
}
}
return dict;
}
const setOfWordsOnThePage = getSetOfWordsOnPage();
function getSelectionText() {
if (window.getSelection) {
return window.getSelection().toString();
} else if (document.selection && document.selection.type !== "Control") {
return document.selection.createRange().text;
}
return "";
}
// Just adding the function as listeners.
document.querySelector("#button").addEventListener("click", () => {
const result = getSelectionText()
.replace(/[^A-Za-z0-9\s]/g, "") // remove punctuation
.split(/\s+/) // split text into words
.filter(word => setOfWordsOnThePage.has(word));
console.log(result);
});
<button id="button">Show result</button>
<p>this is some text</p>
<p>again this is a text!!!!!</p>
<p>another,example,of,a,sentence</p>
也许我们可以更进一步。我们甚至需要记住单词吗?“单词是由空格包围的文本”的定义似乎已经足够了。
为了减少记住页面上单词的不必要开销,并解决部分选择有效单词的错误,我们可以在选择后立即检查所选区域最左侧(锚定)和最右侧(焦点)节点的内容,如果它们包含其他未选择的文本,则忽略它们。
我们在这里做的假设是,对于任意选择的文本,我们最多可以有2个部分选择的单词,每个选择端一个。
注:
下面的方法还通过假设
THIS
tHiS
,及
this
都是同一个词。
function removePunctuation(string) {
return string.replace(/[^A-Za-z0-9\s]/g, " ");
}
function splitIntoWords(string) {
return removePunctuation(string)
.split(/\s+/)
.map(word => word.toLowerCase().trim())
.filter(word => !!word);
}
function getSelectedWords() {
const selection = window.getSelection();
const words = splitIntoWords(selection.toString());
if (selection.anchorNode) {
const startingsWords = splitIntoWords(selection.anchorNode.textContent);
if (words[0] !== startingsWords[0]) {
words.shift(); // remove the start since it's not a whole word
}
}
if (selection.focusNode) {
const endingWords = splitIntoWords(selection.focusNode.textContent);
if (words[words.length - 1] !== endingWords[endingWords.length - 1]) {
words.pop(); // remove the end since it's not a whole word
}
}
return words;
}
// Just adding the function as listeners.
document.querySelector("#button").addEventListener("click", () => {
console.log(getSelectedWords());
});
<button id="button">Show result</button>
<p><div>this is</div> <div>some text</div></p>
<p><span>again</span><span> </span><span>this</span><span> </span><span>is</span><span> </span><span>a</span> <span>text</span><span>!!!!!</span></p>
<p>another,example,of,a,sentence</p>
注:
如果您将单词分解为多个html元素,则此代码仍然会中断
<span>w</span><span>o</span><span>r</span><span>d</span>