Recientemente tuve que deshabilitar a regañadientes el pegado en un elemento de formulario. Para hacerlo, escribí una implementación de navegador cruzado * del controlador de eventos onpaste de Internet Explorer (y otros). Mi solución tenía que ser independiente de las bibliotecas de JavaScript de terceros.
Esto es lo que se me ocurrió. No deshabilita completamente el pegado (el usuario puede pegar un solo carácter a la vez, por ejemplo), pero satisface mis necesidades y evita tener que lidiar con códigos clave, 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);
}
}
}
}
})();
Para hacer uso de esto para deshabilitar el pegado:
<input type="text" onpaste="return false;" />
* Sé que oninput no forma parte de la especificación DOM de W3C, pero todos los navegadores con los que he probado este código (Chrome 2, Safari 4, Firefox 3, Opera 10, IE6, IE7) admiten oninput u onpaste. De todos estos navegadores, solo Opera no admite onpaste, pero sí admite oninput.
Nota: Esto no funcionará en una consola u otro sistema que use un teclado en pantalla (asumiendo que el teclado en pantalla no envía teclas al navegador cuando se selecciona cada tecla). Si es posible que su página / aplicación pueda ser utilizada por alguien con un teclado en pantalla y Opera (por ejemplo: Nintendo Wii, algunos teléfonos móviles), no use este script a menos que haya probado para asegurarse de que el teclado en pantalla envía claves al navegador después de cada selección de clave.