IE8 iframe DesignMode loses selection

前端 未结 3 1480
青春惊慌失措
青春惊慌失措 2021-01-05 18:28

The example below is a simple example of an iframe which uses window.parent.[turn designmode on] (this works). In FF all is well, but in IE8 (surprise surprise) any selectio

3条回答
  •  感动是毒
    2021-01-05 18:52

    You could try saving the selection when the iframe loses focus. If you're sure the content of the iframe will not change before the user focuses on it again, you can store the currently selected Range or TextRange. The following script (for the main page) includes your original script, is not extensively tested and would be improved with better feature detection but is something to work with:

    h_FF=!document.all
    h_rt_F=0
    
    function HLC_DM()
    {
     h_rt_F=document.getElementById("moo").contentWindow
     if(h_FF)
     {
      if(h_rt_F.document.designMode!="on")
      {
       try
       {
        h_rt_F.document.designMode="on"
        h_rt_F.document.execCommand("redo",false,null)
        createEventHandlers();
       }
       catch(e)
       {
        setTimeout("HLC_DM",200)
        return false
       }
      }
     }
     else
      h_rt_F.document.body.contentEditable=true
      createEventHandlers();
    }
    
    
    function getContentWindow() {
     return document.getElementById("moo").contentWindow;
    }
    
    function saveSelection() {
     var win = getContentWindow();
     var doc = win.document;
     var sel = win.getSelection ? win.getSelection() : doc.selection;
     var range;
    
     if (sel) {
      if (sel.createRange) {
       range = sel.createRange();
      } else if (sel.getRangeAt) {
       range = sel.getRangeAt(0);
      } else if (sel.anchorNode && sel.focusNode && doc.createRange) {
       // Older WebKit browsers
       range = doc.createRange();
       range.setStart(sel.anchorNode, sel.anchorOffset);
       range.setEnd(sel.focusNode, sel.focusOffset);
    
       // Handle the case when the selection was selected backwards (from the end to the start in the
       // document)
       if (range.collapsed !== sel.isCollapsed) {
        range.setStart(sel.focusNode, sel.focusOffset);
        range.setEnd(sel.anchorNode, sel.anchorOffset);
       }
      }
     }
     return range;
    }
    
    function restoreSelection(range) {
     var win = getContentWindow();
     var doc = win.document;
     var sel = win.getSelection ? win.getSelection() : doc.selection;
    
     if (sel && range) {
      if (range.select) {
       range.select();
      } else if (sel.removeAllRanges && sel.addRange) {
       sel.removeAllRanges();
       sel.addRange(range);
      }
     }
    }
    
    var selectedRange;
    
    function blurHandler() {
     selectedRange = saveSelection();
    }
    
    function focusHandler() {
     if (selectedRange) {
      restoreSelection(selectedRange);
     }
    }
    
    var iframeHandlersCreated = false;
    function createEventHandlers() {
     // Prevent setting up twice
     if (!iframeHandlersCreated) {
      var iframe = document.getElementById("moo");
      var doc;
      if (iframe.contentDocument && iframe.contentDocument.addEventListener) {
       doc = iframe.contentDocument;
       doc.addEventListener("blur", blurHandler, false);
       doc.addEventListener("focus", focusHandler, false);
      } else if (iframe.attachEvent) {
       iframe.attachEvent("onbeforedeactivate", blurHandler);
       iframe.attachEvent("onfocus", focusHandler);
      }
      iframeHandlersCreated = true;
     }
    }
    

提交回复
热议问题