JS - how to get text between the start of a node position and the current caret (text cursor)?

I need to get the text (or all internal html) of a node truncated to the current cursor position (text cursor) in an element with contenteditable set to true . I tried using range.setStart () etc., but I can not make heads and tails ...

Edit: To clarify some events, I want the script to retrieve text from the beginning of the node, which currently has focus on the caret position (where the blinking vertical line is currently located if the editable field has focus) and save it in Variable . The action is similar to what would happen if the user pressed ctrl + shift + home and ctrl + c

Example: Given html:

 <span contenteditable=true>Hello, world<br> Good bye, World</span> 

And assuming the carriage is between β€œgood” and β€œgoodbye,” I would like to get

"Hello, world<br> Good"

+4
source share
4 answers

You can do this quite easily using Rangy and jQuery .

Here's a jsFiddle demonstrating this approach. Comments explain what is happening.

 $("contenteditable-element").click(function () { // Get the current selection with Rangy var sel = rangy.getSelection() // Insert a temporary caret element at the caret position // (which is inside the contenteditable element) if (sel.rangeCount) sel.getRangeAt(0).insertNode($("<caret />")[0]); // Read the html inside the contenteditable element var innerHTML = $("contenteditable-element").html(); // Clean up, get rid of the caret element $("caret").remove(); // Only keep the text before the first occurrence of the caret element innerHTML = innerHTML.substr(0, innerHTML.indexOf('<caret>')); }); 
+6
source

I would suggest the following approach:

  • create a range that covers the content you need.
  • calling the cloneContents() range method to get a DocumentFragment representing the contents of the range
  • create a <div> or <body> element and add a fragment to it
  • get innerHTML element

Example: http://jsfiddle.net/sUSYG/

code:

 function getHtmlPrecedingSelectionIn(container) { var html = ""; if (window.getSelection && document.createRange) { var sel = window.getSelection(); if (sel.rangeCount > 0) { var selRange = sel.getRangeAt(0); var range = document.createRange(); range.selectNodeContents(container); range.setEnd(selRange.startContainer, selRange.startOffset); var frag = range.cloneContents(); var el = document.createElement("body"); el.appendChild(frag); html = el.innerHTML; } } return html; } 

Cautions:

  • this will not work in IE <= 8, although it is not too difficult to do (either by encoding something using its other select / range API, or using a library like Rangy).
  • the generated HTML is not guaranteed to be a substring of the source HTML of the edit interval.
+5
source

Perhaps this will push you in the right direction: Get the offset of the beginning and end of the range relative to its parent container

I built a fiddle that shows that the function works with your example: http://jsfiddle.net/Kn8qr/2/

 function getCaret(element) { var caretOffset = 0; if (typeof window.getSelection != "undefined") { var range = window.getSelection().getRangeAt(0); var preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(element); preCaretRange.setEnd(range.endContainer, range.endOffset); caretOffset = preCaretRange.toString().length; } else if (typeof document.selection != "undefined" && document.selection.type != "Control") { var textRange = document.selection.createRange(); var preCaretTextRange = document.body.createTextRange(); preCaretTextRange.moveToElementText(element); preCaretTextRange.setEndPoint("EndToEnd", textRange); caretOffset = preCaretTextRange.text.length; } var elCont=element.innerHTML; var truncCont=elCont.substr(0,caretOffset); alert(truncCont); } 

The credit for this belongs to the author of the function, I just edited it abit.

0
source

Take a look at this answer: fooobar.com/questions/194280 / ... I think it does something similar. Perkhapa he shoots on the moon, but he got a working solution :)

0
source

Source: https://habr.com/ru/post/1481626/


All Articles