5

Google Chrome specific - this is an internal-use app that does not require cross-browser compatibility

See http://jsfiddle.net/spetnik/vpcyt4yv/

I have a table into which I am attempting to allow pasting of data. I made the individual cells selectable as such:

<td tabindex="0">

I originally tried adding the onpaste event to the TD elements themselves, but this did not work at all. So instead, I added the event to the table element and just check to make sure that the focused element is a TD and then paste the data to that element:

document.getElementById("tblData").onpaste = function(evt){
    if(document.querySelector(":focus").tagName.toLowerCase() != "td"){
        return;
    }

    document.querySelector(":focus").innerText = evt.clipboardData.getData("text/plain");
};

While this does essentially work, the event usually does not fire on the first attempt. It seems that I need to either a) click around in the table a random number of times (each time is different) or b) change focus to another window and then back again before the event fires. In the jsFiddle I have added a console.log() call to the very beginning of the event so that I can see exactly when the event fires in the debug pane.

See the above jsFiddle or just the result at https://jsfiddle.net/spetnik/vpcyt4yv/embedded/result/

Aaron J Spetner
  • 2,117
  • 1
  • 18
  • 30
  • Even after 7 years this problem & fix still applies. Removing `user-select: none` allows capturning the `onpaste` event. It's a necessary fix for latest Edge and Chrome (Chromium) – Kerwin Sneijders Apr 14 '22 at 07:39
  • @KerwinSneijders now Firefox has the same issue – Aaron J Spetner Apr 14 '22 at 12:58
  • I did not have this issue with the latest version of FireFox using the now normal `user-select: none` – Kerwin Sneijders Apr 14 '22 at 13:51
  • It's weird. See https://jsfiddle.net/spetnik/p4tqmh98/ - in Firefox, the no-select div only receives the paste event if it receives the focus via tabbing. Otherwise once the "select" div has focus, even if you click on the no-select div or anywhere else on the page (except the input) the "select" div still receives the paste event. In Chrome, obviously the "no-select" div will never receive the event, but the "select" event will only receive it if it receives focus via clicking, but not if it receives it via tabbing. – Aaron J Spetner Apr 14 '22 at 20:45

1 Answers1

5

Wow. The culprit seems to be the -webkit-user-select/user-select CSS! I discovered this when I noticed that pasting would be allowed only after initially clicking and dragging the mouse over a cell (which explains the random clicking - only after I clicked until my mouse moved mid-click did it work). I removed this CSS and now it works. Of course, now I need to find a workaround to prevent selecting, but at least I'm no longer stumped.

Edit: It seems that on a normal element (e.g. a DIV with the onpaste set to the element itself) onpaste does not work at all when -webkit-user-select is set to none. I submitted a bug report here

EDIT 2: I have managed to find the following workaround: If I programmatically select the contents of the cell before Ctrl-V is pressed, then it will work, even with -webkit-user-select set to none. I accomplished this by adding the following event handler (jQuery shown here) to the TD (this still does not work in a standalone DIV with -webkit-user-select set to none):

$(elem).click(function(evt){
    var selection = window.getSelection();            
    var range = document.createRange();
    range.selectNodeContents(this);
    selection.removeAllRanges();
    selection.addRange(range);
})
Aaron J Spetner
  • 2,117
  • 1
  • 18
  • 30