Remove Styles from Text When Copying/Cutting Using CSS or JavaScript

Remove Styles from Text when Copying / Cutting using CSS or Javascript

I haven't got time to code up an example now, but you could do this for cut/copy triggered by keyboard shortcuts. It wouldn't work for cut/copy via context menu or Edit menu options because it relies on changing the user selection before the cut or copy event fires.

The steps:

  1. Handle the Ctrl-C and Ctrl-X keyboard shortcuts and the Mac equivalents.
  2. In this handler, create an off-screen element (absolute position and left -10000px, say) and copy the selected content into it. You can do this using window.getSelection().getRangeAt(0).cloneContents(), although you'll need separate code for IE < 9 and you should check the selection is not collapsed.
  3. Do whatever you like to to change the styling of the content of the off-screen element.
  4. Move the selection to encompass the content of the off-screen element so that it is this content that is cut or copied.
  5. Add a brief delay (a few milliseconds) using to window.setTimeout() that calls a function that removes the offscreen element and restores the original selection.

Is it possible to reset the style of content only for copying?

Many many years ago, I made a custom form that replicated the look of a menu on a video game. At the time, Firefox didn't allow many form UI widgets (Firefox 2.something?) to be styled with CSS. Apparently in the last few years that has changed.

What I wound up doing to resolve this problem was creating a very large input text-box with the content passed in via the value="" attribute. (<input type="text", not <textarea)
Despite the ability to style input boxes and their content, this information is not retained when copying the text itself. So I completely side-stepped the issue, and the fixes are live!

It was quite a bit simpler too, absolutely no-JS required.

how to disable copy for particular element in html

Use This CSS Style to disable Selection. By this The Text will not be selected. Thus can't be copied also.

#notcp {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}

is it possible to stop copying text from print preview?

It is not possible to affect the print preview. You can take a look here

But you can prevent people from having that piece of text in the print page entirely.
Something like this:

.disable-select {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@media print{
.disable-select{
display:none
}
}

Edit

There is a way to do that, more a like trick rather than a proper CSS feature, but it works only in modern browsers.

Apparently, using CSS filters will prevent the user from being able to select the text in the Print Preview

@media print{
.disable-text{
filter:grayscale(100%)
}
}

CSS Filter compatibility table

EDIT 2

Also setting the position of fixed elements to relative in the print scenario.


@media print{
.disable-text{
filter:grayscale(100%)
}
.fixed-elements{
position: relative;
}
}

EDIT 3

Or another solution that prevents the fixed elements from being altered is to add the disable-text class to the HTML Tag or to the specific divs where you want to prevent the text from being copied.

Strip external formatting but keep indentation and carriage returns on pre element input

Apologies if I'm stating the obvious here—I get that this doesn't fully solve your problem—but you might be able to do something with the paste event where you grab the paste event's data as text and set the element's innerHTML to that.

This approach may not preserve white space in the way you intend. The skeletal implementation below replaces the contents of the entire element, but you could do something with getSelection to fix that if you went this route:

function onPaste (e) {
e.preventDefault(); // stop the paste
const t = e.clipboardData.getData("text"); // grab the pasted content as plain text
e.target.innerHTML = t; // set the element's innerHTML to the plain text
}

const p = document.getElementById('test');
p.addEventListener('paste', onPaste);
pre {
min-height: 200px;
outline: none;
font-family: monospace;
white-space: pre;
background-color: rgb(19, 22, 27);
color: #98d8e7;
}
<pre id="test" contenteditable></pre>

Filter out HTML Tag onpaste for div and oncopy too

I believe there are 2 ways to do this:

1) The easy way - insert the following code in PasteFilter():

var foo = window.clipboardData.getData('Text');
window.clipboardData.setData('Text', foo);

the first line gets the Text value of clipboardData (already stripped of HTML tags)
and the second line sets the clipboardData to the plain text...
(Tested on IE8)

2) The other way - if for some reason that isn't suitable for you..

In PasteFilter(), you trigger another function with a small delay timeout.
In that function, you get the innerHTML contents of the DIV and run a regular expression to remove all tags.

Example:

function PasteFilter()
{
setTimeout('foo()', 200);
}

function foo()
{
var contents = document.getElementById("test").innerHTML;

var new_contents = contents.replace(/(<([^>]+)>)/g, ""); // taken from http://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/

document.getElementById("test").innerHTML = new_contents;
}

The problem with this method is that you lose the caret position...

Hope this helps...

Prevent user from copying text on mobile browsers

Thanks for your amazing solutions. I tested all of them, and in short some of them worked only on a PC, some only on Chrome and Firefox and some only on Safari, but unfortunately none of them worked 100%.

Although @Max answer might be safest, I didn't tag with PHP in the question because if I use this solution dealing with answers, it will be hard because I don't have access to words on the client side!

So the ultimate solution I came with was combining all of the provided answers plus some new methods (like clearing the clipboard every second) into a jQuery plugin. Now it works on multiple elements too and worked 100% on PC browsers, Firefox, Chrome, and Safari.


What this plugin does

  1. Prevent pasting (optional)
  2. Clearing clipboard (looks like it doesn't work well)
  3. Absorbs all touch events
  4. Disable right click
  5. Disable user selections
  6. Disable pointer events
  7. Add a mask with a z-index inside any selected DOM
  8. Add a transparent div on any selected DOM

A jsFiddle:

(function($) {

$.fn.blockCopy = function(options) {

var settings = $.extend({
blockPasteClass : null
}, options);

if(settings.blockPasteClass){
$("." + settings.blockPasteClass ).bind('copy paste cut drag drop', function (e) {
e.preventDefault();
return false;
});
}

function style_appender(rule){
$('html > head').append($('<style>'+rule+'</style>'));
}

function html_appender(html){
$("body").append(html);
}

function clearClipboard() {
var $temp = $("#bypasser");
$temp.val("You can't cheat !").select();
document.execCommand("copy");
}

function add_absolute_div(id) {
html_appender("<div id='noClick"+id+"' onclick='return false;' oncontextmenu='return false;'> </div>");
}

function absorbEvent_(event) {
var e = event || window.event;
e.preventDefault && e.preventDefault();
e.stopPropagation && e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
return false;
}

function preventLongPressMenu(node) {
node.ontouchstart = absorbEvent_;
node.ontouchmove = absorbEvent_;
node.ontouchend = absorbEvent_;
node.ontouchcancel = absorbEvent_;
}

function set_absolute_div(element,id){
var position = element.position();
var noclick = "#noClick" + id;

$(noclick).css({
height: (element.height()),
width: (element.width()),
position: 'absolute',
top: position.top,
left: position.left,
'z-index': 100
})
}

$("body").bind("contextmenu", function(e) {
e.preventDefault();
});

//Append needed rules to CSS
style_appender(
"* {-moz-user-select: none !important; -khtml-user-select: none !important; -webkit-user-select: none !important; -ms-user-select: none !important; user-select: none !important; }"+
".content {position: relative !important; }" +
".content .mask {position: absolute !important ; z-index: 1 !important; width: 100% !important; height: 100%!important;}" +
".content a {position: relative !important; z-index: 3 !important;}"+
".content, .content .mask{ pointer-events: none;}"
);

//Append an input to clear the clipboard
html_appender("<input id='bypasser' value='nothing' type='hidden'>");

//Clearing clipboard Intervali
setInterval(clearClipboard,1000);

var id = 1;

return this.each( function() {

//Preventing using touch events
preventLongPressMenu($(this));

//Add CSS preventer rules to selected DOM & append mask to class
$(this).addClass("content").append("<div class='mask'></div>");

//Append an absolute div to body
add_absolute_div(id);

//Set position of the div to selected DOM
set_absolute_div($(this),id);

id++;
});
}
}(jQuery));

Usage

$(document).ready(function(){

$(".words").blockCopy({
blockPasteClass : "noPasting"
});

});

HTML for demo:

<div class="words">Test1: Can you copy me or not?</div><br>
<div class="words">Test2: Can you <br> copy me or not?</div><br>
<textarea class="words">Test3: Can you <br>copy me or not?</textarea><br>

<textarea class="noPasting" placeholder="Test1: Paste content if you can" ></textarea><br>

<textarea class="noPasting" placeholder="Test2: Paste content if you can" ></textarea>

Let me know your opinions. Thanks.

Sources

  • Answers to this question

  • Copy text to clipboard

  • Add CSS rule using jQuery

Disable pasting text into HTML form

I recently had to begrudgingly disable pasting in a form element. To do so, I wrote a cross-browser* implementation of Internet Explorer's (and others') onpaste event handler. My solution had to be independent of any third-party JavaScript libraries.

Here's what I came up with. It doesn't completely disable pasting (the user can paste a single character at a time, for example), but it meets my needs and avoids having to deal with keyCodes, etc.

// Register onpaste on inputs and textareas in browsers that don't
// natively support it.
(function () {
var onload = window.onload;

window.onload = function () {
if (typeof onload == "function") {
onload.apply(this, arguments);
}

var fields = [];
var inputs = document.getElementsByTagName("input");
var textareas = document.getElementsByTagName("textarea");

for (var i = 0; i < inputs.length; i++) {
fields.push(inputs[i]);
}

for (var i = 0; i < textareas.length; i++) {
fields.push(textareas[i]);
}

for (var i = 0; i < fields.length; i++) {
var field = fields[i];

if (typeof field.onpaste != "function" && !!field.getAttribute("onpaste")) {
field.onpaste = eval("(function () { " + field.getAttribute("onpaste") + " })");
}

if (typeof field.onpaste == "function") {
var oninput = field.oninput;

field.oninput = function () {
if (typeof oninput == "function") {
oninput.apply(this, arguments);
}

if (typeof this.previousValue == "undefined") {
this.previousValue = this.value;
}

var pasted = (Math.abs(this.previousValue.length - this.value.length) > 1 && this.value != "");

if (pasted && !this.onpaste.apply(this, arguments)) {
this.value = this.previousValue;
}

this.previousValue = this.value;
};

if (field.addEventListener) {
field.addEventListener("input", field.oninput, false);
} else if (field.attachEvent) {
field.attachEvent("oninput", field.oninput);
}
}
}
}
})();

To make use of this in order to disable pasting:

<input type="text" onpaste="return false;" />

* I know oninput isn't part of the W3C DOM spec, but all of the browsers I've tested this code with—Chrome 2, Safari 4, Firefox 3, Opera 10, IE6, IE7—support either oninput or onpaste. Out of all these browsers, only Opera doesn't support onpaste, but it does support oninput.

Note: This won't work on a console or other system that uses an on-screen keyboard (assuming the on-screen keyboard doesn't send keys to the browser when each key is selected). If it's possible your page/app could be used by someone with an on-screen keyboard and Opera (e.g.: Nintendo Wii, some mobile phones), don't use this script unless you've tested to make sure the on-screen keyboard sends keys to the browser after each key selection.



Related Topics



Leave a reply



Submit