禁用将文本粘贴到HTML表单中


96

有没有一种方法可以使用JavaScript禁用将文本粘贴到HTML表单上的文本字段的功能?

例如,我有一个简单的注册表格,要求用户输入两次电子邮件。第二个电子邮件条目是为了验证第一个电子邮件条目中没有错别字。但是,如果用户复制/粘贴他们的电子邮件,那将无法达到目的,并且我一直在遇到用户的问题,因为他们输入了错误的电子邮件并复制/粘贴了它。

也许我不清楚我的问题,但我并没有试图阻止人们在他们的浏览器中复制(或拖动选择)文本。我只是想阻止他们输入粘贴到文本字段中,以最大程度地减少用户错误。

也许您可以使用另一种解决方案来解决我要在此处解决的核心问题,而不是使用此“ hack”?我已经完成了不到六个用户测试,而且已经发生了两次。我的听众没有很高的计算机水平。


111
阻止人们将电子邮件地址从地址簿复制/粘贴到浏览器。那会很好。
昆汀2009年

28
当客户坚持更改时,不能做太多事情。享受你的饮料:)
justinl 2011年

15
如果他仅在未将电子邮件粘贴到原始字段时才禁用在验证字段中的粘贴,那可能会很好。换句话说,用户要么必须将电子邮件粘贴到两个字段中,要么都粘贴到两个字段中。
GJ。

25
如果客户要求这样做,请告诉他们这个想法有多糟糕。这是在客户最有可能离开时(在注册时)生气的好方法。您不希望客户关系从疏远客户开始。随着越来越多的人使用密码管理器,这种做法越来越普遍,并且越来越令人反感。另请参见:ux.stackexchange.com/q/21062/9529和ob。xkcd:xkcd.com/970
Mark Booth,

我在寻找如何克服元素检查器的“功能”时发现了这个问题。有效!
SVD

Answers:


53

我最近不得不禁止在表单元素中粘贴。为此,我编写了Internet Explorer(及其他)onpaste事件处理程序的跨浏览器*实现。我的解决方案必须独立于任何第三方JavaScript库。

这是我想出的。它并没有完全禁止粘贴(例如,用户一次可以粘贴一个字符),但是它满足了我的需求,避免了必须处理keyCodes等。

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

要使用此功能来禁用粘贴:

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

*我知道oninput并不是W3C DOM规范的一部分,但是我测试过此代码的所有浏览器(Chrome 2,Safari 4,Firefox 3,Opera 10,IE6,IE7)都支持oninput或onpaste。在所有这些浏览器中,只有Opera不支持onpaste,但支持oninput。

注意:这在使用屏幕键盘的控制台或其他系统上将不起作用(假设选择了每个键时,屏幕键盘不会将键发送到浏览器)。如果您的页面/应用程序可能被带有屏幕键盘和Opera的人使用(例如Nintendo Wii,某些手机),请不要使用此脚本,除非您已经过测试以确保屏幕键盘每次选择键后,都会将键发送到浏览器。


58
为防止Firefox遵守此愚蠢的规则,请转至about:config并将dom.event.clipboardevents.enabled更改为false
lolesque 2014年

1
即使我不包括您编写的js,也可以通过仅包含来防止用户粘贴任何内容,onpaste="return false"如果我采用这种方法,是否有任何问题
viveksinghggits

@viveksinghggits该代码onpaste在尚不提供此功能的浏览器中实现。您说“ 我能够阻止用户粘贴任何内容 ”,但是您在其中测试了哪些浏览器?
AnnanFay 2016年

关于实现,我看到了两个明显的改进:1)仅在尚不支持onpaste的浏览器中运行代码,2)修改DOM时重新执行-当前不会将其应用于动态添加的输入。
AnnanFay

@Rick,所以您可以使用textareas,用户可以在其中粘贴任何内容?Becuz他们希望它们在显示粘贴数据的其他屏幕中看起来完全相同,并且希望将这些数据插入电子邮件中时看起来完全相同。对我来说,我不希望随之而来的电话和支持电子邮件。禁用粘贴到特定字段是一个可行的选择和问题,恕我直言。我们大多数人遇到的问题是使用“ Rich Text Editors”时-这些东西似乎会覆盖存在的任何javascript或jquery命令以防止粘贴。
McAuley

144

不要这样 不要搞乱用户的浏览器。通过复制+粘贴到电子邮件确认字段中,用户将对其键入的内容承担责任。如果他们愚蠢到足以复制并粘贴错误的地址(这是我的事),那是他们自己的错。

如果要确保可以完成电子邮件确认,请让用户在站点等待时检查其电子邮件(“请在新窗口中打开Webmail程序”)。用大写字母显示电子邮件地址(“确认电子邮件已发送至...。出错了?请单击此处进行更改)。

如果可以的话,更好的做法是让用户具有某种受限的访问权限而无需确认。这样,他们可以立即登录,即使确认邮件由于其他原因(例如垃圾邮件过滤器)被阻止,也可以提高与访客保持联系的机会。


6
对于用户自己输入数据的情况,我同意您的回答。但是,当用户代表其他人(例如CRM系统或类似系统)输入电子邮件地址时,实施您的解决方案是不可行的。在这些情况下,用户不是输入自己的电子邮件地址,因此他们可能会拼写错误。如果您允许粘贴到电子邮件确认框,那么您将得到很多不正确的数据,因此防止粘贴没有任何问题。作为开发人员,您必须减轻“愚蠢”用户的负担,以保护企业数据。
theyetiman 2013年

12
还有一种常见情况是,开发人员在看这个问题时几乎无法控制他们正在处理的项目的需求。这不是对此处提出的问题的答案,因此为-1。
尼克

4
说不做并不能回答问题。我目前有一个要求禁用粘贴的要求。
Darian Everett

13
如果您曾经被要求过这样的要求,那么作为专家,您的工作就是推销它。您不仅仅可以编写代码。
丹·潘特里

2
但是,几乎所有事情都有正当理由,而且没有回答某人的问题,因为您认为其正当理由令人讨厌。假设您有一个测验,您尝试使用复杂的答案来实施。禁用粘贴并强迫学生键入整个答案而不是复制粘贴将使他们将答案提交到内存中,而仅复制粘贴可能会毫无用处。有充分理由这样做。警告某人在大多数情况下他们尝试做的事不是一个好主意,但要给出答案……否则最好不要打扰答复。
Halfhoot

69

在要禁用复制粘贴功能的输入中添加“ disablecopypaste”类,并添加此jQuery脚本

  $(document).ready(function () {
    $('input.disablecopypaste').bind('copy paste', function (e) {
       e.preventDefault();
    });
  });

1
坦克,对我来说很好用!
加布里埃尔·格劳伯

26

刚得到这个,我们就可以使用来实现它onpaste:"return false",这要感谢:http : //sumtips.com/2011/11/prevent-copy-cut-paste-text-field.html

我们还有以下列出的各种其他选项。

<input type="text" onselectstart="return false" onpaste="return false;" onCopy="return false" onCut="return false" onDrag="return false" onDrop="return false" autocomplete=off/><br>

16

您可以.....但是不能。

您不应该更改用户浏览器的默认行为。对于您的Web应用程序,这确实是不好的可用性。另外,如果用户想禁用此黑客,则只需在其浏览器上禁用javascript。

只需将这些属性添加到文本框中

ondragstart=”return false onselectstart=”return false

6
问题是关于禁用粘贴。这种技术只会使复制变得困难,而根本不会影响粘贴。
bentman

10

疯狂的主意:在注册过程中,要求用户向您发送电子邮件。当单击mailto链接不起作用时(例如,如果他们使用的是webmail),这显然很不方便,但是我认为这是一种同时防止输入错误并确认电子邮件地址的方法。

它将是这样的:他们填写了大部分表单,输入了他们的姓名,密码和其他内容。当他们按下“提交”时,他们实际上是在单击链接以将邮件发送到您的服务器。您已经保存了他们的其他信息,因此该消息仅包含一个令牌,说明该帐户用于哪个帐户。


哈,那是个好主意。
justinl

7

将确认电子邮件发送到用户刚刚输入两次的电子邮件地址,其中在您的站点上有一个指向确认URL的链接,那么您知道他们已经收到消息了,该怎么办?

任何不单击以确认电子邮件已收到的人,可能输入了错误的电子邮件地址。

这不是一个完美的解决方案,而只是一些想法。


4
我目前有此实现。问题在于,由于我们检查错误,用户认为他们没有收到电子邮件,因为他们检查了认为自己输入的电子邮件地址,并且没有电子邮件。同样发生的是,当他们尝试重新注册时,他们使用的用户名现在不可用,因为该用户名被该错误的电子邮件地址所卡住。
justinl

Tnen可能会添加一些工作流/代码,这些代码每天都会运行清除用户名超过2天未确认的用户名。
科林

1
感谢您的评论。我的想法是,如果您尝试在网站上创建一个帐户并说出您的用户名已被使用,您是否会在两天内再次返回并重试一次?我的想法很可能不会。您要么在同一天用不同的用户名创建了一个新帐户,要么您因为不想弄清楚如何注册以及该网站“太复杂”而不必费心回到该网站。
justinl

8
继续Colin所说的,您可以假设当某人尝试使用相同的用户名和不同的电子邮件地址重新注册并且他们没有回复确认消息时,可以允许他们这样做。您可能会发现人们在他们的电子邮件中获得了正确的域名,但是拼写了错误的用户名,并且可以使用它来进一步确定某人何时犯了错?
理查德·卢卡斯

1
我非常喜欢允许用户重新注册尚未确认其帐户信息的想法。我认为该设计解决方案比我最初提出的技术解决方案要好。从其他所有人那里听到,更改此默认浏览器功能不是一个好主意,这是我找到更好的解决方案所需要的。
justinl


6

扩展@boycs答案,我建议也使用“ on”。

$('body').on('copy paste', 'input', function (e) { e.preventDefault(); });

如果计划将脚本应用于动态添加的表单元素,则此方法很有用。
马修

3

如果您必须使用2个电子邮件字段,并且担心用户不正确地将相同类型错误的电子邮件从字段1粘贴到字段2,那么我想说如果用户将某些内容粘贴到第二个电子邮件字段中,则会显示警报(或更细微的内容)

document.querySelector('input.email-confirm').onpaste = function(e) {
    alert('Are you sure the email you\'ve entered is correct?');
}

这样,您就不会禁用粘贴,您只需给他们一个友好的提醒,以检查他们大概在第一个字段中键入了什么,然后粘贴到第二个字段中是正确的。

但是,可能只需要一个具有自动完成功能的电子邮件字段即可。他们有可能在某个时间之前正确地填写了电子邮件,然后又在另一个站点上浏览器会建议用该电子邮件填写该字段

<input type="email" name="email" required autocomplete="email">

2

您可以将“ keydown”侦听器附加到输入框,以检测是否按下了Ctrl + V键,如果是,则停止事件或将输入框的值设置为”。

但是,这将无法处理右键单击以及粘贴或从浏览器的“编辑”菜单粘贴的问题。您可能需要在keydown侦听器中添加一个“ last length”计数器,并使用一个间隔来检查字段的当前长度,以查看自上次击键以来该字段的长度是否增加。

两者都不推荐。禁用粘贴的表单域非常令人沮丧。我能够在第一次正确输入电子邮件,因此保留将其粘贴到第二个框中的权利。


不是右键单击,甚至不是来自Apple,Unix或ctrl-ins的任何东西,iPhone呢?
Martlark

我也不喜欢禁用输入字段,因为我发现这很烦人。但是,阻止这种类型的用户错误的其他选择是什么?还是哪种解决方案将以最少不正确地完成用户注册而告终?不得不再次手动输入电子邮件地址似乎有些烦人,但是如果要保存沮丧的潜在客户,那么我宁愿强迫用户在输入字段中手动输入内容。我认为这不是一个很大的麻烦,它可以使某人从一个简单的错误中解脱出来的挫败感可能是值得的。有什么想法吗?
justinl

2

在注册过程中增加第二步。通常照常显示第一页,但重新加载后,显示第二页并再次询问电子邮件。如果那很重要,则用户可以处理。


1

有些人可能建议使用Javascript捕获用户的操作,例如右键单击鼠标或Ctrl + C / Ctrl + V组合键,然后停止操作。但这显然不是最佳或最简单的解决方案。该解决方案与使用Javascript捕获的事件一起集成在输入字段属性本身中。

为了禁用浏览器的自动完成功能,只需将属性添加到输入字段。它看起来应该像这样:

<input type="text" autocomplete="off">

并且,如果您想拒绝该字段的“复制和粘贴”,只需添加捕获oncopy,onpaste和oncut调用的Javascript事件,并使它们返回false,如下所示:

<input type="text" oncopy="return false;" onpaste="return false;" oncut="return false;">

下一步是使用onselectstart拒绝用户输入字段的内容选择,但要警告:这仅适用于Internet Explorer。以上其余部分在所有主要浏览器上均能正常运行:Internet Explorer,Mozilla Firefox,Apple Safari(至少在Windows OS上)和Google Chrome。


虽然从理论上讲这可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。
凯夫

是的,下次我会照顾
vaichidrewar 2011年

1
为什么不现在开始描述“很好的解释”呢,这就是获得投票和更好的代表的方法:)
Kev

(尝试)关闭自动完成功能有什么理由?“我们讨厌我们的用户!” ?如果您想成为用户的敌人,那么他们会恨您,而他们最终还是会赢,因为他们控制着浏览器。
Jan Hertsens

1

检查给定电子邮件主机的MX记录的有效性。这样可以消除@符号右侧的错误。

您可以在提交表单之前和/或在提交服务器端之前通过AJAX调用来完成此操作。


1

使用jQuery,您可以避免使用此方法粘贴粘贴和剪切

$('.textboxClass').on('copy paste cut', function(e) {
    e.preventDefault();
});

谢谢。这确实可以正常工作。


1

使用Jquery,您可以使用一个简单的代码行来做到这一点。

HTML:

<input id="email" name="email">

码:

$(email).on('paste', false);

JSfiddle:https ://jsfiddle.net/ZjR9P/2/



0

简单的解决方案:只需逆转注册过程即可:无需在注册过程结束时要求确认,而在开始时要求确认!也就是说,注册过程从一个简单的表格开始,要求输入电子邮件地址,仅此而已。提交后,一封电子邮件带有指向确认页面的链接,该确认页面是所发送的电子邮件地址所独有的。用户转到该页面,然后将请求其余的注册信息(用户名,全名等)。

这很简单,因为在确认之前该网站甚至不需要存储任何内容,因此可以使用密钥对电子邮件地址进行加密并作为确认页面地址的一部分进行附加。


0

我为http://bookmarkchamp.com做过类似的事情 -我想在那里检测用户何时将某些内容复制到HTML字段中。我想出的实现方法是不断检查该字段,以查看其中是否突然有很多文本。

换句话说:如果毫秒前一次没有文本,而现在有超过5个字符,则用户可能在该字段中粘贴了一些内容。

如果您想在Bookmarkchamp中看到此功能(需要注册),请将URL粘贴到URL字段中(或在其中拖放URL)。


0

我解决确认电子邮件地址问题的方法如下:

  1. 在执行主要流程之前(例如注册用户),首先请他们输入电子邮件地址。
  2. 生成唯一的代码并将其发送到该电子邮件地址。
  3. 如果用户输入了正确的电子邮件地址,他们将获得验证码。
  4. 用户必须输入该代码以及他们的电子邮件地址和其他所需信息,以便他们完成注册。-请注意,如果这次他们输入了错误的电子邮件地址(或错误的代码),因为它与代码不匹配,则注册将无法进行,并会立即通知用户。
  5. 如果正确输入了电子邮件地址,代码和其他注册信息,则注册已完成,用户可以立即开始使用系统。-无需响应其他任何电子邮件地址即可激活其帐户

为了获得更好的安全性,该代码应具有有限的生存期,并且在注册过程中应仅允许一次。此外,为了防止任何恶意的机器人应用程序,最好将第一步与验证码或类似机制一起进行。


0

您可以通过贝娄脚本禁用jQuery的复制粘贴选项。jQuery(“ input”)。attr(“ onpaste”,“ return false;”);

通过使用波纹管oppaste在输入字段中属性。

onpaste =“ return false;”


-1
Hope below code will work :

<!--Disable Copy And Paste-->
<script language='JavaScript1.2'>
function disableselect(e){
return false
}
function reEnable(){
return true
}
document.onselectstart=new Function ("return false")
if (window.sidebar){
document.onmousedown=disableselect
document.onclick=reEnable
}
</script>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.