Sex*_*ast 16 javascript jquery contenteditable
我有一个contenteditable div,我需要在当前的插入位置知道这个词.我试过这个解决方案,但问题是,它不能识别像@和的特殊字符~.因此,如果一个单词开始~,就像~fool,我正在得到fool,而我期待~fool.所以我尝试修改解决方案时考虑到如果在移回选择后,遇到的字符不是空格,我会继续向后移动直到遇到空格.这将成为选择的开始.同样地,我会继续前进,直到找到一个空格,这标志着选择的结束.然后选择会给我这个词.为了获得插入位置,我使用了这个解决方案.结合起来,我的代码现在看起来像这样:
function getCaretPosition(editableDiv) {
var caretPos = 0,
sel, range;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
if (range.commonAncestorContainer.parentNode == editableDiv) {
caretPos = range.endOffset;
}
}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
if (range.parentElement() == editableDiv) {
var tempEl = document.createElement("span");
editableDiv.insertBefore(tempEl, editableDiv.firstChild);
var tempRange = range.duplicate();
tempRange.moveToElementText(tempEl);
tempRange.setEndPoint("EndToEnd", range);
caretPos = tempRange.text.length;
}
}
return caretPos;
}
function getCurrentWord() {
var sel, word = "";
if (window.getSelection && (sel = window.getSelection()).modify) {
var selectedRange = sel.getRangeAt(0);
sel.collapseToStart();
sel.modify("move", "backward", "word");
while (sel.toString() != " " && getCaretPosition($("#editor").get(0)) != 0) {
sel.modify("move", "backward", "character");
(sel = window.getSelection()).modify;
}
sel.modify("move", "forward", "character");
sel.modify("extend", "forward", "word");
word = sel.toString();
// Restore selection
sel.removeAllRanges();
sel.addRange(selectedRange);
} else if ((sel = document.selection) && sel.type != "Control") {
var range = sel.createRange();
range.collapse(true);
range.expand("word");
word = range.text;
}
return word;
}
$(function () {
$(document).on('keyup keydown paste cut mouseup',"#editor", function () {
var word = getCurrentWord();
console.log(word);
});
});
Run Code Online (Sandbox Code Playgroud)
然而,这根本不起作用.那是问题.1.问题2是,即使图片中有图像并且用户点击图片,处理程序仍然会在图像之前返回最后一个单词,而我期待一个空白字符串.任何人都可以帮我解决这两个问题吗?
我修改了getCurrentWord()函数以使用基本的String方法从插入符号位置获取单词.该函数接受元素和位置,并返回该位置的单词.
以下是更新的功能.
function getCurrentWord(el, position) {
// Get content of div
var content = el.textContent;
// Check if clicked at the end of word
position = content[position] === ' ' ? position - 1 : position;
// Get the start and end index
var startPosition = content.lastIndexOf(' ', position);
var endPosition = content.indexOf(' ', position);
// Special cases
startPosition = startPosition === content.length ? 0 : startPosition;
endPosition = endPosition === -1 ? content.length : endPosition;
return content.substring(startPosition + 1, endPosition);
}
Run Code Online (Sandbox Code Playgroud)
该函数首先获取元素的内容.接下来,它会检查用户是否点击在词的结尾,如果是,那么从位置减去一个,以便indexOf与lastIndexOf将在太空正常工作.
对于开始和结束位置,有两个特殊情况需要处理.首先,单击最后一个元素.为此,startPosition将-1在最后一个单词后面没有空格.
其次,当点击第一个单词时,endPosition将是-1因为在第一个单词之前可能没有空格.
即使在最后一个字符之后的第一个字符和空格之前有空格,这两个条件也会起作用.
indexOf并lastIndexOf用于查找单词前后的空格,使用这些索引substring将在该位置给出单词.
这是现场演示测试.
$(function() {
function getCaretPosition(editableDiv) {
var caretPos = 0,
sel, range;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
if (range.commonAncestorContainer.parentNode == editableDiv) {
caretPos = range.endOffset;
}
}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
if (range.parentElement() == editableDiv) {
var tempEl = document.createElement("span");
editableDiv.insertBefore(tempEl, editableDiv.firstChild);
var tempRange = range.duplicate();
tempRange.moveToElementText(tempEl);
tempRange.setEndPoint("EndToEnd", range);
caretPos = tempRange.text.length;
}
}
return caretPos;
}
function getCurrentWord(el, position) {
var word = '';
// Get content of div
var content = el.textContent;
// Check if clicked at the end of word
position = content[position] === ' ' ? position - 1 : position;
// Get the start and end index
var startPosition = content.lastIndexOf(' ', position);
startPosition = startPosition === content.length ? 0 : startPosition;
var endPosition = content.indexOf(' ', position);
endPosition = endPosition === -1 ? content.length : endPosition;
return content.substring(startPosition + 1, endPosition);
}
$('#editor').on('keyup keydown paste cut mouseup', function() {
var caretPosition = getCaretPosition(this);
var word = getCurrentWord(this, caretPosition);
console.log(word);
});
});Run Code Online (Sandbox Code Playgroud)
div {
font-size: 18px;
line-height: 1.5em;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editor" contenteditable>
Lorem !p$um dolor $!t @met, con$ectetur @d!p!$!c!ng el!t, $ed do e!u$mod tempor !nc!d!dunt ut l@bore et dolore m@gn@ @l!qu@. Ut en!m @d m!n!m ven!@m, qu!$ no$trud exerc!t@t!on ull@mco l@bor!$ n!$! ut @l!qu!p ex e@ commodo con$equ@t. Du!$ @ute !rure dolor
!n reprehender!t !n volupt@te vel!t e$$e c!llum dolore eu fug!@t null@ p@r!@tur.
</div>Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的例子。有一个带有示例文本的 div:
<div contenteditable onclick="getCaretCharacterOffsetWithin(this)">some ~test content</div>
Run Code Online (Sandbox Code Playgroud)
这是脚本。当我们单击 div 时,无论光标落在哪里,我们都会获取当前位置并吐出我们所在的单词。该单词可以包含特殊字符,并且仅用空格分隔。
function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(element);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
console.log('caretOffset', caretOffset);
word = getWordAtPosition(caretOffset, element);
console.log('word', word);
return caretOffset;
}
function getWordAtPosition(position, element) {
var total_text = element.innerHTML;
var current_word = "";
var i = 0;
var word_found = false;
while(i < total_text.length) {
if(total_text[i] != ' ')
current_word += total_text[i];
else if(word_found)
return current_word;
else
current_word = "";
if(i == position)
word_found = true;
i++;
}
return current_word;
}
Run Code Online (Sandbox Code Playgroud)
下面是它的工作示例:
https://codepen.io/anon/pen/dWdyLV