2017-05-07 15 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

相關問題