JavaScript get clipboard data on paste event (Cross browser)

前端 未结 20 2386
小蘑菇
小蘑菇 2020-11-21 11:22

How can a web application detect a paste event and retrieve the data to be pasted?

I would like to remove HTML content before the text is pasted into a rich text edi

20条回答
  •  一生所求
    2020-11-21 11:42

    This was too long for a comment on Nico's answer, which I don't think works on Firefox any more (per the comments), and didn't work for me on Safari as is.

    Firstly, you now appear to be able to read directly from the clipboard. Rather than code like:

    if (/text\/plain/.test(e.clipboardData.types)) {
        // shouldn't this be writing to elem.value for text/plain anyway?
        elem.innerHTML = e.clipboardData.getData('text/plain');
    }
    

    use:

    types = e.clipboardData.types;
    if (((types instanceof DOMStringList) && types.contains("text/plain")) ||
        (/text\/plain/.test(types))) {
        // shouldn't this be writing to elem.value for text/plain anyway?
        elem.innerHTML = e.clipboardData.getData('text/plain');
    }
    

    because Firefox has a types field which is a DOMStringList which does not implement test.

    Next Firefox will not allow paste unless the focus is in a contenteditable=true field.

    Finally, Firefox will not allow paste reliably unless the focus is in a textarea (or perhaps input) which is not only contenteditable=true but also:

    • not display:none
    • not visibility:hidden
    • not zero sized

    I was trying to hide the text field so I could make paste work over a JS VNC emulator (i.e. it was going to a remote client and there was no actually textarea etc to paste into). I found trying to hide the text field in the above gave symptoms where it worked sometimes, but typically failed on the second paste (or when the field was cleared to prevent pasting the same data twice) as the field lost focus and would not properly regain it despite focus(). The solution I came up with was to put it at z-order: -1000, make it display:none, make it as 1px by 1px, and set all the colours to transparent. Yuck.

    On Safari, you the second part of the above applies, i.e. you need to have a textarea which is not display:none.

提交回复
热议问题