Insert text into editable IFRAME at carriage position (IE)

I'm really struggling with the problem: in Internet Explorer, I want to insert plain text at the current position of the caret. This works fine for simple TEXTAREA elements, but it doesn't fully work for editable IFRAMEs, which is what I have.

In the script I use I create a TextRange object from the IFRAME document, which I use to insert text in the HTML at the cursor position.

<iframe id="editable"> <html> <body> Some really boring text. </body> </html> </iframe> <script type="text/javascript"> window.onload = function() { var iframe = document.getElementById('editable'); var doc = iframe.contentDocument || iframe.contentWindow.document; doc.body.innerHTML = iframe.textContent || iframe.innerHTML; // Make IFRAME editable if (doc.body.contentEditable) { doc.body.contentEditable = true; } } function insert(text) { var iframe = document.getElementById('editable'); var doc = iframe.contentDocument || iframe.contentWindow.document; iframe.focus(); if(typeof doc.selection != 'undefined') { var range = doc.selection.createRange(); range.pasteHTML(text); } } </script> <input type="button" value="Insert" onClick="insert('foo');"/> 

When I select the text in IFRAME, the selection will be replaced by "foo" - this is the expected behavior. But when I just put the caret somewhere in the text, the insert will not work.

Is this the usual behavior since there is no โ€œreal choiceโ€ for the case when I just put the cursor somewhere or is it a bug with editable IFRAMEs in IE, since it works fine with simple TEXTAREA elements?

Is there a workaround?

+4
source share
1 answer

You can find it if you use onmousedown and not onclick in your button.

UPDATE

The reason this matters is because the click event is fired after the iframe loses focus (which destroys minimized selection in IE), whereas mousedown fires earlier.

ADDITIONAL UPDATE

You can also try to fix this in IE by saving / restoring the selected TextRange, as the iframe loses / gets focus. Something like this should work:

 function fixIframeCaret(iframe) { if (iframe.attachEvent) { var selectedRange = null; iframe.attachEvent("onbeforedeactivate", function() { var sel = iframe.contentWindow.document.selection; if (sel.type != "None") { selectedRange = sel.createRange(); } }); iframe.contentWindow.attachEvent("onfocus", function() { if (selectedRange) { selectedRange.select(); } }); } } window.onload = function() { var iframe = document.getElementById('editable'); fixIframeCaret(iframe); }; 
+6
source

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


All Articles