2017-05-07 16 views
15

我有一个contenteditable div,我需要知道当前插入符号处的单词。我试过this solution,但问题是,它不识别特殊字符,如@~。所以,如果一个词开始~,如~fool,我得到fool,而我预计~fool。所以我试图修改解决方案,考虑到如果将选择移回后,遇到的角色不是空格,我会继续向后移动,直到遇到空格。这将使选择的开始。同样,我会继续前进直到找到空间,这将标志着选择的结束。然后选择会给我这个词。为了得到插入位置,我使用了this solution。结合起来,我的代码现在看起来像这样:在contenteditable div中获取以特殊字符开头的单词在插入符号处的词

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); 
    }); 
}); 

但是,这根本不起作用。这是问题没有。 1.问题2是,即使图片中有图像,用户点击图片,图片处理程序不断返回最后一个图片,但我期待空白字符串。任何人都可以帮我解决这两个问题吗?

+0

我不想成为那个人,但它听起来像2个回答你有你需要放在一起工作解决方案为您的需要的一切之间。你不必标记任何一个答案是对的,只是认为你有足够的解决方案来为自己工作:P –

+0

我也在自己尝试一些东西,我不是懒洋洋地坐在别人的工作解决方案上。 – SexyBeast

+0

我的歉意,我并没有打算暗示你是懒惰的。只是意味着这两个答案之间我认为答案是潜伏的。 –

回答

2

这是一个相当准确的例子。有一个与示例文本的div:

<div contenteditable onclick="getCaretCharacterOffsetWithin(this)">some ~test content</div> 

这是脚本。当我们点击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; 
} 

继承人它的一个例子的工作:

https://codepen.io/anon/pen/dWdyLV

+1

嗯。几乎可以工作。除了在您提供的代码中,如果我点击单词的末尾,即现在光标在单词'〜test'的末尾闪烁,则显示的单词是“内容”,它是由下一个单词分隔的单词空间。其次,如果我点击单词的开头,以便光标在该单词的第一个字符之前闪烁,对于单词'〜test',它将返回'〜test',对于其他词如'hello'以'〜'开始,它返回' ' – SexyBeast

+0

更不用说,如果你使'〜test'字变为粗体,返回的单词是'〜test'而不是'〜test',然后点击后面的'内容'字仍然收益'〜测试'。 – SexyBeast

+0

首先想到的是:选择'〜test'不合需要?我认为要做的最简单的事情就是写出一个特定的特殊字符列表,用来表示分隔字符并从那里开始。 –

5

我修改了getCurrentWord()功能使用基本字符串的方法来从插入位置得到了这个词。该函数接受元素和位置并返回该位置处的单词。

下面是更新后的功能。

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); 
} 

函数首先获取元素的内容。接下来,它会检查用户是否点击了单词的结尾,如果是,则从该位置减去一个,以使indexOflastIndexOf在空间上正常工作。

对于开始和结束位置,有两个特殊情况需要处理。首先,点击最后一个元素。为此,startPosition将是-1,因为在最后一个单词之后可能没有空格。

其次,当单击第一个单词时,endPosition将为-1,因为在第一个单词之前可能没有空格。

即使在最后一个字符之后的第一个字符和空格之前有空格,这两个条件也会起作用。

indexOflastIndexOf用于查找单词之前和之后的空格,并使用这些索引substring将该单词放在该位置。

这里的live demo来测试。

$(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); 
 
    }); 
 
});
div { 
 
    font-size: 18px; 
 
    line-height: 1.5em; 
 
}
<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 [email protected] et dolore [email protected]@ @[email protected] Ut en!m @d m!n!m [email protected], qu!$ no$trud [email protected]!on [email protected] [email protected]!$ n!$! ut @l!qu!p ex [email protected] commodo [email protected] Du!$ @ute !rure dolor 
 
    !n reprehender!t !n [email protected] vel!t e$$e c!llum dolore eu [email protected] [email protected] [email protected][email protected] 
 
</div>

+1

仍然是大量的错误。例如,在你提供的示例内容中,如果你点击第三个单词 - dolor,然后做一个“CTRL-B”使其变成粗体,然后再次点击它,它开始给出错误的单词。如果双击一个单词来选择它,而不是记录该单词,则会记录错误的单词。 – SexyBeast

相关问题