javascript - 无法通过选择 api 在空格后选择刚刚写的单词
问题描述
window.getSelection()
我很快就学会了选择 api,我找不到一个真正的教程来解释它的document.createRange()
所有sel.offsetNode
内容使用选择时的缺陷 - 我决定学习它只是为了创建一个简单的文本编辑器,它可以突出显示文本并介绍一些建议- 几乎我在第一点就成功了 50% 我可以通过匹配方法搜索单词所以当用户写这个单词时它会突出显示它但问题是该
match
方法将执行代码并重复文本因为它已经可以匹配它-我认为最好的解决方案是只获取所写的单词,就像想象我有这段文字welcome in our page
一样我只是这个文本,当点击空白开始时,让我在空格后得到新单词的字母,比如 android 键盘,每次我写新单词时都会引入新的建议
这是我尝试过的
var div = document.getElementsByTagName("div")[0],
sel = window.getSelection(),
range = document.createRange();
function move() {
range.selectNodeContents(div);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
}
div.addEventListener("keyup", function () {
if(this.innerHTML.match(/(keyword)[^\>keyword\<]/ig)) {
this.innerHTML = this.innerText.replace(/\</ig, "<").replace(/\>/ig, ">").replace(/keyword/ig, function(word) {
let x = "<span style='color: crimson'>"+word.toLowerCase()+"</span>";
return x
});
move()
}
})
- 用户输入也可以包含一些 html 标签,所以我替换了它们
- 我也尝试过类似
sel.offsetNode.data
的东西,但它让我得到了 div 的整个文本 - 我需要任何帮助,因为我真的很困惑
解决方案
注意事项
- 新行:每个浏览器都以不同的方式执行此操作。有些换行在 a 中
<div>
,有些在 a 中<p>
,我认为 IE 插入了一个<br>
? 关键是,每个浏览器都不同。 - 如果他们按Backspace在
keyword
文本内部怎么办?我们要删除突出显示吗? - 从技术上讲,插入符号(闪烁的文本插入点)算作大小为 0 的选择。所以当我们 时
removeAllRanges
,它会移动到文本的开头 --- 这不是我们想要的! - 这是一个糟糕的 API。
比赛计划
我对你想要发生的事情有点困惑,但你提到你想要一些类似于 Android / iOS 键盘自动完成建议的东西。所以,我们要做的就是提取插入符号之前的单词。
为此,每当他们键入时,我们都需要:
- 找到插入符号的位置。
- 在文本中找到插入符号位置在内部/之后的单词。
找到插入符号位置
如前所述,插入符号只是开始和结束位置相同的范围。因此,我们可以获取第一个范围,通过检查这些数字是否相同来检查它是否不是选择,然后获取起始偏移量以获取插入符号位置:
let caret = window.getSelection().getRangeAt(0);
if (caret.startOffset == caret.endOffset) {
console.log(caret.startOffset);
}
寻找相关词
如果我们得到插入符号的容器(不是它<div>
本身,因为记住带有换行符的文本可能在嵌套元素中,等等),那么我们可以找到它的文本内容。这样,我们就可以找到插入符号所在的字符,然后向后循环,直到找到一个空格或点击元素的开头。这将为我们提供我们需要选择的文本。
let text = caret.startContainer.textContent;
let wordStart = 0;
let wordEnd = caret.startOffset;
for (let i = wordEnd; i >= 0; i--) {
if (text[i] == " ") {
wordStart = i;
break;
}
}
console.log(text.slice(wordStart, wordEnd));
把它们放在一起
let editor = document.getElementById("editor");
let suggestions = document.getElementById("suggestions");
editor.addEventListener("keyup", function () {
let caret = window.getSelection().getRangeAt(0);
// Is it only a caret --- e.g. they have no other text selected
if (caret.startOffset == caret.endOffset) {
// Find the start point: work backwards from the caret until
// we find a space character.
let text = caret.startContainer.textContent;
let wordStart = 0;
let wordEnd = caret.startOffset;
for (let i = wordEnd; i >= 0; i--) {
if (text[i] == " ") {
wordStart = i + 1;
break;
}
}
// Display the word
suggestions.innerHTML = text.slice(wordStart, wordEnd);
}
});
#editor {
border: solid 1px #000;
padding: 10px;
}
#suggestions {
color: crimson;
}
<div id="editor" contenteditable="true"></div>
Current word: <span id="suggestions"></span>
推荐阅读
- bash - Bash 脚本问题
- android - 当第 4 次出现时在页面上显示广告
- python - 如何为项目列表创建标签列表?
- php - SOAP - 加载本地 WSDL 文件
- apache-flink - Flink 1.6.0 作业 jar 上传大小限制
- java - 无法在 linux mint 17 上打开 STS
- python - 在redis中扫描键时是否有推荐的计数大小?
- vb.net - 无法在 Visual Basic 中对从系统获取的文件进行排序
- fortran - 正确设置随机种子以实现可重复性
- wordpress - 未捕获的类型错误:无法读取 null wp-embed.min.js 的属性“秘密”