在 Javascript 中,我编写了一个脚本,用于在用户单击某个单词时突出显示该单词。
这个问题在某些地方已经得到了回答。我已经利用这些解决方案中的答案来创建这个运行得很好的脚本。
$(".clickable").click(function(e){
var selectedVocabPhrase = null
var matchedVocabPhrase = null
var selection = window.getSelection()
if (selection.anchorNode.parentNode.nodeName === 'STRONG') {
selectedVocabPhrase = selection.anchorNode.parentNode.innerText
}
if (!selection || selection.rangeCount < 1) return true;
var range = selection.getRangeAt(0);
var node = selection.anchorNode;
var word_regexp = /^\w*$/;
// Extend the range backward until it matches word beginning
while ((range.startOffset > 0) && range.toString().match(word_regexp)) {
range.setStart(node, (range.startOffset - 1));
}
// Restore the valid word match after overshooting
if (!range.toString().match(word_regexp)) {
range.setStart(node, range.startOffset + 1);
}
// Extend the range forward until it matches word ending
while ((range.endOffset < node.length) && range.toString().match(word_regexp)) {
range.setEnd(node, range.endOffset + 1);
}
// Restore the valid word match after overshooting
if (!range.toString().match(word_regexp)) {
range.setEnd(node, range.endOffset - 1);
}
console.log(range.toString().trim());
});
JSBIN 链接在这里...
https://jsbin.com/faxibolebu/edit?html,js,console,output
但是,存在问题/例如,如果一个单词有 hypth - 例如 co-worker,那么如果单击 co,则只会突出显示 co。如果单击“worker”,则仅突出显示“worker”。类似的问题也发生在包含撇号的单词上,例如不能。这个词被 split 了。
我无法解决这个问题。如有任何帮助,我们将不胜感激。
最佳答案
不要匹配 \w*
- 仅匹配单词字符 - 考虑匹配 \S*
,它匹配任何非空格字符。
为了排除尾随 .
和 ,
,请将 (?![.,])\S
添加到末尾 (向前查找除 .
或 ,
之外的任何内容,然后匹配任何非空格字符)。
此外,如果用户故意单击并拖动来选择文本,您可能会考虑按原样保留现有的突出显示(这对用户更加友好,并避免奇怪和/或模棱两可的行为,例如当选择多个单词时)。通过检查 startOffset
是否等于 endOffset
来执行此操作:
$(".clickable").click(function(e) {
var selectedVocabPhrase = null
var matchedVocabPhrase = null
var selection = window.getSelection()
if (selection.anchorNode.parentNode.nodeName === 'STRONG') {
selectedVocabPhrase = selection.anchorNode.parentNode.innerText
}
if (!selection || selection.rangeCount < 1) return true;
var range = selection.getRangeAt(0);
if (range.startOffset !== range.endOffset) {
// User selected at least one character themselves; don't change anything
return;
}
var node = selection.anchorNode;
var word_regexp = /^(?:|\S*(?![.,])\S)$/;
// Extend the range backward until it matches word beginning
while ((range.startOffset > 0) && range.toString().match(word_regexp)) {
range.setStart(node, (range.startOffset - 1));
}
// Restore the valid word match after overshooting
if (!range.toString().match(word_regexp)) {
range.setStart(node, range.startOffset + 1);
}
// Extend the range forward until it matches word ending
while ((range.endOffset < node.length) && range.toString().match(word_regexp)) {
range.setEnd(node, range.endOffset + 1);
}
// Restore the valid word match after overshooting
if (!range.toString().match(word_regexp)) {
range.setEnd(node, range.endOffset - 1);
}
console.log(range.toString().trim());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="clickable">
<div>
<div>
<div class="v-popover">
<span aria-describedby="popover_8k4slo118o" tabindex="-1" class="trigger" style="display: inline-block;">
<span>When office worker Laura Garzón visited a butcher's shop in Bogota, she <strong>couldn't believe her eyes</strong>.
</span>
</span>
</div>
<div class="v-popover">
<span aria-describedby="popover_tb8xft1vhg" tabindex="-1" class="trigger" style="display: inline-block;">
<span> Standing behind the counter was her co-worker, Jorge Castro.
</span>
</span>
</div>
<div class="v-popover"><span aria-describedby="popover_1b3s8fw9ee" tabindex="-1" class="trigger" style="display: inline-block;">
<span style="cursor: pointer; display: inline !important;"> But instead of wearing a suit and tie, he was wearing a bloodstained butcher's apron and white cap.
</span>
</span>
</div>
</div>
</div>
</div>
关于javascript - 突出显示句子中单击时的单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60199437/