简体   繁体   中英

Chrome & IE: onpaste event not firing?

I (like many others) am trying to sanitise text that I'm pasting into a contentEditable iframe. I'm not using jQuery (it's a very ancient code base) and the handler is attached like so:

if (isIE) {
  iframe.attachEvent("onpaste",handler);
}
else {
  iframe.addEventListener("paste",handler,true);
}

This works in Firefox and Opera, but in IE 10 and the latest version of Chrome (29.0.1547.62), the handler is never called; I put a breakpoint at the first line of the handler, but when paste I some text it doesn't reach the breakpoint and the pasted text just appears (unsanitised). I tried using IE10 in IE 9 mode and it makes no difference. Other handlers seem to be called as expected.

Does anyone have any idea what might be going on here?

TIA...

It turns out the iframe is loaded with a blank page and then programmatically filled with content. The event listener was being added prior to rewriting the iframe document, and this was the cause of the problem. The listener needs to be added after the iframe content has been rewritten. Here's a test case:

<html>
<head>
<title>Paste test&</title>
<script>
  function handler() {
    alert("Paste");
  }

  function register(iframe) {
    //
    //  IE10 requires addEventListener to be used, so this
    //  is preferable to doing browser detection...
    //
    if (window.addEventListener) {
      iframe.addEventListener("paste",handler,true);
    }
    else {
      iframe.attachEvent("onpaste",handler);
      }
  }

  function test() {
    var iframe = document.getElementById("frm").contentWindow;
    try {
      var doc = iframe.document;
      if (!doc) {
        setTimeout(test,50);
        return;
      }
//      register(iframe);   // this won't work!
      doc.open();
      doc.write("<html><body>Paste text here: []</body></html>");
      doc.close();
      doc.body.contentEditable = true;
      register(iframe);     // this works!
    }
    catch (e) {
      setTimeout(test,50);
      return;
    }
  }
</script>
</head>
<body onLoad="test()">
Here is the iframe:
<p>
<iframe id="frm" src="blank.html" width="400" height="200"></iframe>
</body>

I guess your iframe refers to the iframe element on the main page (though in this case I couldn't get this work even in FF23). You could use a cross-browser way to refer the window object within the iframe instead:

HTML:

<iframe name="iframe" ...></iframe>

JS:

var iframe = window.frames['iframe'];
if (window.addEventListener) {
  iframe.addEventListener('paste', handler);
}
else {
  iframe.attachEvent('onpaste', handler);
}

Notice also the feature detection instead of browser detection.

What comes to Chrome, I'm not sure, I couldn't test the code locally, since looks like -allow-access-to-files doesn't work in Chrome29.

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