【问题标题】:Restrict HTML input to only allow paste将 HTML 输入限制为仅允许粘贴
【发布时间】:2014-03-03 13:53:29
【问题描述】:

是否可以在只接受粘贴输入的表单上进行 HTML 输入?

作为我们注册过程的一部分,最终用户需要在基本的 HTML 输入表单中输入一个 20 个字符的标识令牌。理想情况下,用户只需将令牌复制/粘贴到适当的字段中即可。我们不想让用户手动输入,因为他们很可能会输入错误的字母,而且我们没有任何可靠的方法来验证输入。

令牌来自桌面软件,需要粘贴到已打开的网页中(即他们从哪里下载软件)。因此,可点击的链接不是一个可行的选择。

有没有办法做到这一点,例如通过Javascript?谢谢。


我的解决方案,改编自 SimplePi 的回答:

<html>
<body>
<script type="text/javascript">
 function validate(evt) {
   var theEvent = evt || window.event;
   var key = theEvent.charCode || theEvent.which;

   if(key >= 32 && (theEvent.ctrlKey === undefined || !theEvent.ctrlKey)) {
    if(theEvent.preventDefault) theEvent.preventDefault();
    else theEvent.returnValue = false;
  }
 }
 </script>
  <span>Textbox name</span> <br />
 <input type="text" onkeypress='validate(event)' value=""/>
</body>
</html>

这适用于某些浏览器,但并非所有浏览器。 Mac 上的 Firefox 是我发现的唯一违规者 - 一般报告中的 Firefox ctrl-vv 完全相同,但在 Windows 上,theEvent.ctrlKey 成员可以区分两者。在 mac 上做同样的事情显然需要 keydown/up 来检查是否按下了 cmd。这是可行的,但不包含在此代码中,以防其他人希望使用它。

【问题讨论】:

  • 我很确定这是可能的,但这将是一个非常糟糕的用户体验。无论如何,大多数用户都会复制/粘贴令牌 ID,那么为什么要为最少的用户付出额外的努力呢?
  • 您必须同时允许键盘快捷键粘贴(可能因操作系统而异)和右键单击上下文菜单粘贴。另外,是什么阻止他们粘贴与您的令牌完全不同的东西?
  • 他们从哪里获得令牌?
  • @ajp15243 没有什么可以阻止他们粘贴到随机文本中,尽管我们可以强制文本必须恰好是 20 个字符。这是为了防止用户错误地误输入一个(或多个)字母,而这将无法检测到。
  • @DylanStreb 我很确定这是可能的,但需要大量投资和测试以确保它不包含任何隐藏的、大洞。为什么不让他们输入两三次密钥以确保他们没有输入错误呢?如果他们像大多数人一样复制/粘贴,这将很快而且不容易出错。如果他们的打字方式与大多数人不同,那么他们以同样的方式输入错误两到三遍的几率比一次要低得多。

标签: javascript html textfield paste


【解决方案1】:

这是一个更强大的解决方案,我在上面的代码上进行了扩展。可能有点矫枉过正,但它适用于所有浏览器。下面的代码将:

  1. 使文本框像只读一样,但会尊重标签索引并设置焦点
  2. 支持win和mac鼠标或键盘的所有剪贴板功能
  3. 允许撤消、重做和全选

$( "#your_textbox" ).keypress(function(evt) {
	// Note this could be a bit of overkill but I found some
	// problems in Firefox and decided to go the distance
	// including old windows keyboard short cut keys.
	// Enumerate all supported clipboard, undo and redo keys
	var clipboardKeys = {
		winInsert : 45,
		winDelete : 46,
		SelectAll : 97,
		macCopy : 99,
		macPaste : 118,
		macCut : 120,
		redo : 121,	
		undo : 122
	}
	// Simulate readonly but allow all clipboard, undo and redo action keys
	var charCode = evt.which;
	//alert(charCode);
	// Accept ctrl+v, ctrl+c, ctrl+z, ctrl+insert, shift+insert, shift+del and ctrl+a
	if (
		evt.ctrlKey && charCode == clipboardKeys.redo ||		/* ctrl+y redo			*/
		evt.ctrlKey && charCode == clipboardKeys.undo ||		/* ctrl+z undo			*/
		evt.ctrlKey && charCode == clipboardKeys.macCut ||		/* ctrl+x mac cut		*/
		evt.ctrlKey && charCode == clipboardKeys.macPaste ||		/* ctrl+v mac paste		*/
		evt.ctrlKey && charCode == clipboardKeys.macCopy ||		/* ctrl+c mac copy		*/ 
		evt.shiftKey && evt.keyCode == clipboardKeys.winInsert ||	/* shift+ins windows paste	*/ 
		evt.shiftKey && evt.keyCode == clipboardKeys.winDelete ||	/* shift+del windows cut	*/ 
		evt.ctrlKey && evt.keyCode == clipboardKeys.winInsert  ||	/* ctrl+ins windows copy	*/ 
		evt.ctrlKey && charCode == clipboardKeys.SelectAll		/* ctrl+a select all		*/
		){ return 0; }
	// Shun all remaining keys simulating readonly textbox
	var theEvent = evt || window.event;
	var key = theEvent.keyCode || theEvent.which;
	key = String.fromCharCode(key);
	var regex = /[]|\./;
	if(!regex.test(key)) {
		theEvent.returnValue = false;
		theEvent.preventDefault();
	}
});

【讨论】:

  • 我最喜欢你的解决方案。出色的跨浏览器/系统支持。
  • 同意,这是最好的答案。
【解决方案2】:
<script type="text/javascript">
 function validate(evt) {
   var theEvent = evt || window.event;
   var key = theEvent.keyCode || theEvent.which;
   key = String.fromCharCode(key);
  var regex = /[]|\./;
   if(!regex.test(key)) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
  }
 }
 </script>
  <span>Textbox name</span>
 <input name="ReceiveNo" type="text" class="txtbox" onkeypress='validate(event)' value=""         required tabindex="" />

【讨论】:

  • 这似乎只是将文本框限制为仅数字,并且还禁止粘贴任何文本。
  • @DylanStreb 我修复了数字问题。粘贴效果很好。在我自己的服务器上检查过。
  • 只需执行key != 22 而不是key = String.fromCharCode(key);,正则表达式似乎可以工作,因为 22 是按 ctrl-v 时设置为键的值。右键菜单不受影响。这样做可能是解决方案,但我需要更彻底地测试它。谢谢。
  • 做了一些更彻底的测试并进行了一些更改。我已经用我的修改更新了我的原始帖子,这主要是有效的。谢谢。
【解决方案3】:

为什么还要让他们粘贴呢?如果您通过电子邮件发送验证令牌,则只需通过电子邮件将它们发送到http://example.com/verify/{{TOKEN}},然后从那里获取其余的注册过程。

【讨论】:

  • 抱歉,更新了更多细节:令牌是从桌面应用程序获取的。这是他们需要应用到其用户帐户的物理设备的序列号。
猜你喜欢
  • 2013-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
相关资源
最近更新 更多