Intercept Paste Event in JavaScript

Intercept paste event in Javascript

You can intercept the paste event by attaching an "onpaste" handler and get the pasted text by using "window.clipboardData.getData('Text')" in IE or "event.clipboardData.getData('text/plain')" in other browsers.

For example:

var myElement = document.getElementById('pasteElement');
myElement.onpaste = function(e) {
var pastedText = undefined;
if (window.clipboardData && window.clipboardData.getData) { // IE
pastedText = window.clipboardData.getData('Text');
} else if (e.clipboardData && e.clipboardData.getData) {
pastedText = e.clipboardData.getData('text/plain');
}
alert(pastedText); // Process and handle text...
return false; // Prevent the default handler from running.
};

As @pimvdb notes, you will need to use "e.originalEvent.clipboardData" if using jQuery.

Intercept Paste data in JavaScript

Just add a paste event listener to the document.

document.addEventListener("paste", function (e) {
console.log(e.target.id);
var pastedText = undefined;
if (window.clipboardData && window.clipboardData.getData) { // IE
pastedText = window.clipboardData.getData('Text');
} else if (e.clipboardData && e.clipboardData.getData) {
pastedText = e.clipboardData.getData('text/plain');
}
e.preventDefault();
e.target.value = "You just pasted '" + pastedText + "'";
return false;
});

fiddle

jquery intercepting paste event

Maybe this is what your trying to do, not 100% sure:

HTML:

<input type="text" id="test" class="myInput" value="This is some default text" />​

jQuery:

$(document).ready(function () {
$('input').on('paste', function (e) { //Attach paste event handler for all inputs
$(this).val('').val(e.target.value); //Clear the current value, then insert the value of the data that was pasted
});
});

Fiddle: http://jsfiddle.net/PMq6U/

Intercept paste event inside a variable in jquery

The problem is because getAsString() is asynchronous, therefore you're attempting to read c before the value has been set.

To fix this extract the logic dependant on c in to its own function and call that function in the callback of getAsString():

$('body').on('paste', function(e) {  var c = "";  var dt = e.originalEvent.clipboardData;
if (dt && dt.items && dt.items[0]) { dt.items[0].getAsString(function(text) { $('.log').text(text); doStuff(text); }); } else { if (dt && ('getData' in dt)) { $('.log').text(dt.getData('text')); doStuff(dt.getData('text')); } }});
function doStuff(foo) { console.log('You pasted', foo);}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><p>  Pasted text: <span class="log"></span></p>

JavaScript get clipboard data on paste event (Cross browser)

The situation has changed since writing this answer: now that Firefox has added support in version 22, all major browsers now support accessing the clipboard data in a paste event. See Nico Burns's answer for an example.

In the past this was not generally possible in a cross-browser way. The ideal would be to be able to get the pasted content via the paste event, which is possible in recent browsers but not in some older browsers (in particular, Firefox < 22).

When you need to support older browsers, what you can do is quite involved and a bit of a hack that will work in Firefox 2+, IE 5.5+ and WebKit browsers such as Safari or Chrome. Recent versions of both TinyMCE and CKEditor use this technique:

  1. Detect a ctrl-v / shift-ins event using a keypress event handler
  2. In that handler, save the current user selection, add a textarea element off-screen (say at left -1000px) to the document, turn designMode off and call focus() on the textarea, thus moving the caret and effectively redirecting the paste
  3. Set a very brief timer (say 1 millisecond) in the event handler to call another function that stores the textarea value, removes the textarea from the document, turns designMode back on, restores the user selection and pastes the text in.

Note that this will only work for keyboard paste events and not pastes from the context or edit menus. By the time the paste event fires, it's too late to redirect the caret into the textarea (in some browsers, at least).

In the unlikely event that you need to support Firefox 2, note that you'll need to place the textarea in the parent document rather than the WYSIWYG editor iframe's document in that browser.

How to capture paste event anywhere on page in React?

  1. Your listener will only work when the specific div is focused, therefore it works on the second attempt. Instead, add the listener to body element or window object:
function Component() {
const [inputText, setInputText] = useState(false);

useEffect(() => {
window.addEventListener("paste", (e) => {
setInputText(e.clipboardData.getData("text"));
});

return () => {
window.removeEventListener("paste");
};
}, []);

return <div className="App">{inputText}</div>;
}

Edit Paste Listener



  1. am I right in thinking it's best to pass a callback

No, it depends on the depth, please read about Context API and research on an anti-pattern called "props-drilling".

Angular - On Paste Event Get Content

You can get the pasted content from the paste event and the updated content of the textarea by handling the input event:

<textarea #myText (paste)="onPaste($event)" (input)="onInput(myText.value)"></textarea>

with this code:

onPaste(event: ClipboardEvent) {
let clipboardData = event.clipboardData || window.clipboardData;
let pastedText = clipboardData.getData('text');
...
}

onInput(content: string) {
...
}

See this stackblitz for a demo.

Undo an overridden paste in JS

I found a way to make it work. Starting with this answer, I changed it to use .focus() instead of .select(), which fixes the pasting. Then, to make pasting work in Firefox, I had to keep the fallback that doesn't preserve undo history. This will have to do until Firefox fixes the bug (See bug report).

function insertAtCaretTrim(element, text) {    element[0].focus();    // Attempt to preserve edit history for undo.    var inserted = document.execCommand("insertText", false, $.trim(text));      // Fallback if execCommand is not supported.    if (!inserted) {        var caretPos = element[0].selectionStart;        var value = element.val();
// Get text before and after current selection. var prefix = value.substring(0, caretPos); var suffix = value.substring(element[0].selectionEnd, value.length);
// Overwrite selected text with pasted text and trim. Limit to maxlength. element.val((prefix + $.trim(text) + suffix).substring(0, element.attr('maxlength')));
// Set the cursor position to the end of the paste. caretPos += text.length; element.focus(); element[0].setSelectionRange(caretPos, caretPos); }}
var $inputs = $("input");
$inputs.each(function () { $(this).on('paste', function (evt) { var clipboardData = evt.originalEvent.clipboardData || window.clipboardData; var pastedData = clipboardData.getData('text/plain');
// Trim the data and set the value. insertAtCaretTrim($(this), pastedData); evt.preventDefault(); });});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><input type="text" maxvalue="10" />

Detect a paste event in a contenteditable

UPDATE:

All major browsers now give you access to the clipboard data in a paste event. See Nico Burns's answer for an example on newer browser and also check out Tim Down's answer if you need to support older browsers.


You can listen for the onPaste event on the div to detect the paste. If you just want to disable the paste you can call event.preventDefault() from that listener.

To capture the pasted content however is a little bit more difficult since the onPaste event does not give you access to the pasted content. The usual way to handle this is to do the following from the onPaste event handler:

  • create a dummy div and place it outside the window boundaries so it's not visible to visitors
  • move the focus to this div
  • call a sanitizer method using a setTimeout(sanitize, 0)

and from your sanitizing method:

  • find the dummy div and get it's contents
  • sanitize the HTML and remove the div
  • move the focus back to the original div
  • insert the sanitized content in the original div


Related Topics



Leave a reply



Submit