Zakázat vkládání textu do formuláře HTML

Existuje způsob, jak pomocí JavaScriptu zakázat možnost vkládání textu do textového pole ve formuláři HTML?

Mám například jednoduchý registrační formulář, kde je uživatel povinen zadat svůj e-mail dvakrát. Druhý e-mailový záznam slouží k ověření, že v prvním e-mailovém záznamu nejsou žádné překlepy. Pokud však uživatel zkopíruje/vloží svůj e-mail, pak to maří účel a uživatelé mají problémy, protože zadali nesprávný e-mail a zkopírovali/vložili jej.

Možná jsem ve své otázce neměl jasno, ale nesnažím se lidem bránit v kopírování (nebo přetahování výběru) textu ve svém prohlížeči. Chci jim jen zabránit v vkládání zadejte do textového pole, abyste minimalizovali chyby uživatele.

Možná místo použití tohoto „hacku“ můžete navrhnout jiné řešení hlavního problému toho, co se zde snažím vyřešit? Provedl jsem méně než půl tuctu uživatelských testů a toto se již stalo dvakrát. Mé publikum nemá vysokou úroveň počítačových znalostí.

Odpověď

Nedávno jsem musel neochotně zakázat vkládání do prvku formuláře. Abych to udělal, napsal jsem implementaci obslužné rutiny události onpaste pro Internet Explorer (a další) pro různé prohlížeče*. Moje řešení muselo být nezávislé na JavaScriptových knihovnách třetích stran.

Zde je to, na co jsem přišel. Úplně to nezakazuje vkládání (uživatel může například vložit jeden znak najednou), ale vyhovuje mým potřebám a nemusí se zabývat keyCodes atd.

// 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);
                }
            }
        }
    }
})();

Chcete-li toto využít k zakázání vkládání:

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

* Vím, že oninput není součástí specifikace W3C DOM, ale všechny prohlížeče, se kterými jsem tento kód testoval – Chrome 2, Safari 4, Firefox 3, Opera 10, IE6, IE7 – podporují buď oninput, nebo onpaste. Ze všech těchto prohlížečů pouze Opera nepodporuje onpaste, ale podporuje oninput.

Poznámka:Toto nebude fungovat na konzoli nebo jiném systému, který používá klávesnici na obrazovce (za předpokladu, že klávesnice na obrazovce neposílá klávesy do prohlížeče, když je vybrána každá klávesa). Pokud je možné, že by vaši stránku/aplikaci mohl používat někdo s klávesnicí na obrazovce a Operou (např.:Nintendo Wii, některé mobilní telefony), nepoužívejte tento skript, pokud jste neotestovali klávesnici na obrazovce odešle klíče do prohlížeče po každém výběru klíče.