I have the usual such iframe , inside is the same simple text and for highlighting some areas use a span with a certain class. But here's the problem, if the cursor is behind the last character of the text in this span , then the text is typed only into it, and you need to type after the span . The problem with a set of ordinary characters was solved by creating a span outside the current one and highlighting it with a range , but with a space, some miracles ...

Thanks in advance for your help.

You can pokoldovat here -> http://jsfiddle.net/np7a0cLe/ , because here the code for security reasons will not work at all ...

 $(function(){ isIE = /*@cc_on!@*/false; frame = $('#text').get(0); frameDoc = isIE ? frame.contentWindow.document : frame.contentDocument; frameDoc.open(); frameDoc.write($('#iframeDoc').text()); frameDoc.close(); frameDoc.designMode = "on"; $(frameDoc).on('keydown', 'body', function(event) { var keyCodesList = [ 8, 35, 36, 37, 38, 39, 40, 46 ], // Список клавиш на которые не нужно реагировать selection = frame.contentWindow.getSelection(); if ($.inArray(event.keyCode, keyCodesList) == -1) { // Если Node уже помечен как невалидный (родитель редактируемого элемента не body) if (selection.isCollapsed && selection.anchorNode.parentElement != document.body && selection.anchorOffset == selection.anchorNode.length) { var curRange = selection.getRangeAt(0), range = document.createRange(), Span = document.createElement('span'); Span.innerHTML = "&nbsp"; $(Span).insertAfter(curRange.endContainer.parentElement); range.selectNode(Span); selection.removeAllRanges(); selection.addRange(range); } } }); }); 
 .invalid { background-color: #CC7777; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> Iframe:<br /> <iframe id="text"></iframe> <textarea style="display: none;" id="iframeDoc"> <html> <head> <meta charset="utf-8"> <style> body { margin: 0px; padding: 0px; font-family: 'Open Sans', 'Arial', sans-serif; font-size: 13px; line-height: 26px; } .invalid { background-color: #CC9999; } </style> </head> <body contenteditable="true"> Какой то текст <span class="invalid">(-blabla-)</span></body> </html> </textarea> 

    1 answer 1

    Exit found. The space needs to be placed inside the created span and specify a non-zero position for the caret, selectNodeContents is also not suitable for this. The problem is that an extra space is added.

     $(function(){ isIE = /*@cc_on!@*/false; frame = $('#text').get(0); frameDoc = isIE ? frame.contentWindow.document : frame.contentDocument; frameDoc.open(); frameDoc.write($('#iframeDoc').text()); frameDoc.close(); frameDoc.designMode = "on"; $(frameDoc).on('keydown', 'body', function(event) { var keyCodesList = [ 8, 35, 36, 37, 38, 39, 40, 46 ], // Список клавиш на которые не нужно реагировать selection = frame.contentWindow.getSelection(); if ($.inArray(event.keyCode, keyCodesList) == -1) { // Если Node уже помечен как невалидный (родитель редактируемого элемента не body) if (selection.isCollapsed && selection.anchorNode.parentElement != document.body && selection.anchorOffset == selection.anchorNode.length && selection.anchorNode.parentElement.classList.contains('invalid')) { var curRange = selection.getRangeAt(0), range = document.createRange(), Span = document.createElement('span'); Span.innerHTML = "&nbsp"; $(Span).insertAfter(curRange.endContainer.parentElement); if (event.keyCode == 32) { range.setStart(Span, 1); range.collapse(true); }else{ range.selectNode(Span); } selection.removeAllRanges(); selection.addRange(range); } } }); });