Does Safari handle the paste event correctly?

2019-04-06 17:08发布

问题:

I'm trying to write some code for Safari for handling the 'paste' event, but it doesn't seem to work right. According to the WebKit DOM reference, oncut, onpaste, and oncopy are all handled more-or-less like the W3C Clipboard API suggests. However, it doesn't work like I expect. I'm pasting image data, but as far as I've been able to tell, the problem I'm having applies to any kind of paste. This jsfiddle works just fine in Chrome, but not in Safari 6.0.4 on OSX.

$(function () {
    console.log("ready");
    $("#pastearea").on("paste", function (e) {
        e.preventDefault();
        console.debug("testing paste in safari");
        var blob = e.originalEvent.clipboardData.items[0].getAsFile();
        console.debug(blob);
        var reader = new FileReader();
        reader.onload = readerLoaded;

        reader.readAsDataURL(blob);
    });
});

function readerLoaded(e) {
    $("#dest").attr("src", e.target.result);
}

I tried again using just plain JS. Still no joy:

<div id="pastearea" onpaste="plainjsOnPaste()" style="width: 100px; height: 100px; background-color: blue;"/>

function plainjsOnPaste(e) {
    console.log("blahblahblah");
    console.log(e);   
}

If there's some issue with Safari, then obviously I shouldn't expect jQuery to work. As far as I can tell, in the second attempt (plain) I'm doing exactly what the WebKit reference suggests I should do, but it doesn't work at all. Is this some known limitation of Safari, or is the problem between the chair and keyboard?

Update: it seems that Safari doesn't implement the W3C's working draft of the Clipboard APIs. I'm researching workarounds, but if anyone knows one I'd love to heard it.

回答1:

I think the answer, as unsatisfying as it might be, is "no". See this WebKit bug:

https://bugs.webkit.org/show_bug.cgi?id=75891

If your intention is to receive paste data into something that's not contentEditable, a text input or a text area, I don't know of any method to make the current version of Safari do this.

Update: an attempted work-around in this JSFiddle, simplified to only deal with text, does not work in Safari 6.0.5. It attempts a work-around where a hidden text field is automatically focused when Cmd-V is pressed, just in order to enable pasting in Safari. It does prevent the "you can't paste beep", but no paste event is sent and nothing is pasted into the secret input.

$(function () {
    $(window).bind('keydown', function (e) {
        // Cmd-V
        if (e.which == 86 && e.metaKey) {
            if (e.target.nodeName.toUpperCase() !== "INPUT")
                $('#secretinput').focus();
        }
    });

    $(window).bind('beforepaste', function (e) {
        return false;
    });

    $(window).bind('paste', function (e) {
        var clipboardData = e.originalEvent.clipboardData;
        console.log(clipboardData);
        $('#textdest').html(clipboardData.getData('text/plain'));
    });
});


回答2:

Don't know if it helps you, but I use a out-of-screen input to force safari accept paste on the page. It helped me so here it goes:

I'm doing:

script:

$(document).bind('paste', function(e) {
    var data = e.originalEvent.clipboardData.getData('Text');
    // here using data from clipboard
});

$(function(){
   $('input.special').focus();
});

css:

input.special{
position:absolute;
top:-40px;
}

html:

<input type="text" class="special" style="position: absolute;top:-40px;">