简体   繁体   中英

Recording and restoring the position of the caret within a contenteditable div using textangular

I've seen a lot of code snippets detailing how to get and set the caret position within a contenteditable div but I cannot get it to work in my case:

I am using a WYSIWYG text editor (textAngular). I have included functionality for the user to insert a cross-reference at the cursor position. They click a button, which opens up a dialog box for them to make selections from, which in turn will insert a html node at the current cursor position.

The location of the cursor may be within child nodes within the div such as p tags and/or other formatting tags.

My issue is that the current cursor position is lost when the dialog gains focus. I have tried storing the caret position (node and offset) in memory before opening the dialog but whatever I try the caret position always returns to the start of the div. I've tried all the code snippets I can find on stackoverflow but none of them work. I assume I am missing something.

EDIT: On second thoughts, your issue is probably that when you click the button the content editable looses focus and hence the selection is lost. We handle this as so in textAngular: toolElement.attr('unselectable', 'on');

Best solution for this is to use rangy instead of roll-your-own (required in textAngular ^1.3.0).

You've probably been down voted due to this being very similar to SO questions about "save and restore" caret position in content-editables eg Saving and Restoring caret position for contentEditable div

In the case of textAngular we've dealt with this issue multiple times and we have some shortcuts and helpers built into the TA (textAngular) toolbar tools. Have a look at any of the issues here: https://github.com/fraywing/textAngular/search?q=modal&type=Issues

If you have TA specific questions it's often best to look through the 500+ issues on the github repository. Chances are something similar has been attempted before.

From this answer: Saving and Restoring caret position for contentEditable div

Modified to your use case. When the combo ctrl + i is pressed a popup appears. You interact with the popup and press the close button, and then the cursor position is returned to it's original.

Without any other code this is what I had to go on.
I used jquery to make coding the example less verbose, but this also works without jquery.

  function getRestorePosition(context) { var selection = window.getSelection(); var range = selection.getRangeAt(0); range.setStart( context, 0 ); var len = range.toString().length; return function restore(){ var pos = getTextNodeAtPosition(context, len); selection.removeAllRanges(); var range = new Range(); range.setStart(pos.node, pos.position); selection.addRange(range); } } function getTextNodeAtPosition(root, index){ var lastNode = null; var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT,function next(elem) { if(index > elem.textContent.length){ index -= elem.textContent.length; lastNode = elem; return NodeFilter.FILTER_REJECT } return NodeFilter.FILTER_ACCEPT; }); var c = treeWalker.nextNode(); return { node: c ? c: root, position: c? index: 0 }; } $('[contenteditable="true"]').on('keydown',function(e) { if(e.ctrlKey && e.which == 73) { var popup = $('#popup'); var restore = getRestorePosition(e.target); popup.show(); popup.find('button').one('click',function() { popup.hide(); restore(); }); e.preventDefault(); return false; } }); 
 #popup { position:absolute; background-color:rgba(100,100,100,0.8); left:0px; right:0px; bottom:0px; top:0px; display:none; color:white; text-align:center; padding:0px;200px; font-size:3em; } [contenteditable="true"] { border:1px solid gray; padding:20px; font-size:2em; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div contenteditable="true"> How much wood could a woodchuck chuck if a woodchuck could chuck wood </div> <div id="popup"> A wood chuck could chuck as much wood as a woodchuck could chuck!<BR/> <button>close</button> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM