使用 jQuery 防止 html 输入中的值

Posted

技术标签:

【中文标题】使用 jQuery 防止 html 输入中的值【英文标题】:Preventing values in html inputs with jQuery 【发布时间】:2012-07-03 02:18:18 【问题描述】:

如果输入框中的组合值与他们最新的按键没有传递正则表达式,我如何防止用户更改输入框中的字符串?

我看到了各种关于如何使用按键来测试单个字符的示例,但我需要将整个值与正则表达式匹配,而不仅仅是他们按下的键。

例如,文本框需要符合以下正则表达式:

"^023-[0-9]0,7$"

因此,如果他们想将"023" 更改为"23",则应该在他们删除0 字符时阻止他们。在023 之后删除- 也是如此。一旦他们在023 之后输入超过 7 个数字,它也应该阻止他们。 这不能在模糊时完成。必须在每次击键后完成。 性能不是问题。

如果我在 jQuery 中使用 keypress() 事件,并像这样获取输入元素的值:

$(this).val()

然后我只会在他们按下键之前得到值 - 而不是之后。因此,无法针对我的正则表达式测试输入。我不能简单地将按下的键附加到这个字符串,因为我不能假设他们只在字符串的最右侧输入键

我研究了 keydown/keyup 事件,虽然 keyup 似乎在用户按下某个键后给了我输入的当前值,但我发现很难消除他们键入的内容的影响...... keypress() 显然没有问题。

var regex = new RegExp("^023-[0-9]0,7$");

$("#number").keyup(function(event) 
    var number = $(this).val();

    if(!regex.test(number)) 
        event.preventDefault();

        return false;
    
);

上面的代码不起作用。似乎 keypress() 使我能够停止他们键入的内容,但 keyup 使我能够获取当前值。我需要一个两者兼得的解决方案;)

问题实际上源于浏览器没有 MVC 架构这一事实。模型就是视图。不幸的是,我们无法在视图更新之前验证更新的模型......因为我们需要在 keyup 事件期间更新视图以获取更新的模型数据......到那时,阻止它们更新已经为时已晚查看,因为它已经更新了。

【问题讨论】:

您应该考虑对模糊进行验证。每次击键都针对正则表达式运行并不是提高性能的最佳主意。 @jbabey:不过,我总是必须将 023- 保留在现场。要求规定用户永远不能改变这一点。 那么 023- 应该在框旁边的标签(或只读输入)中,而不是在同一个框中。 @jbabey:要求说它必须在同一个盒子里。 那么我会推迟要求;) 【参考方案1】:

这个怎么样:

var prevValue = "";
$("#number").keydown(function(e) 
   prevValue = $(this).val();
);

$("#number").keyup(function(e) 
...
   if(!regex.test(number))
      $(this).val(prevValue);
      // show error or other processing you need to do
);

【讨论】:

大约一个小时前我也试过这个。如果您按住字符而不是仅仅按下它们,您会发现它没有按预期工作。问题是这并不能阻止他们首先实际编辑文本——它只是在事后替换它,这已经太晚了。这不是一个非常强大的解决方案。【参考方案2】:

试试这个:

var pattern = new RegExp("^023-[0-9]0,7$");

$("#number").change(function(e)
if (!pattern.test($(this).val())) 
      return false
    
)

【讨论】:

我同意这个解决方案。验证应该发生在模糊(或更改)上,而不是每次击键。 @undefined:要求规定用户不能更改“023-”。如果我诉诸模糊类型的事件,那么用户可以更改它。要求还规定它必须全部放在一个文本框中。【参考方案3】:

您拥有的event 参数将包含您正在处理的事件的所有详细信息。这将包括被按下的键。

值得注意的是keydownkeyup 事件将返回按下的键,而keypress 将返回输入的哪个字符可能更适合您的选择。

请参阅此处的帮助页面:http://api.jquery.com/keypress/ 了解更多详情。

总之,虽然event.which 应该做你想做的事。您可以将其与文本框的原始值结合起来,并从中获取新值。如果无效则取消事件,如果有效则放手...

【讨论】:

我对他们按下的键不感兴趣。我对输入的总价值更感兴趣。键“2”有时有效,有时无效。这取决于他们按下键后元素的值。 但你当然可以做$(this).val()+event.which... '不确定你的问题出在哪里...... 你为什么假设输入的文本总是在字符串的末尾? @egervari:我认为只是一个粗心的假设。 ;-) 我只是没想过将角色放在其他地方...我很欣赏答案现在不再有用但可能会留在那里以防万一有人出现并且对您的最后一个字符唯一约束感到满意指出。【参考方案4】:

如果您可以使用 jQuery Validate 插件,您可以创建自定义验证器来匹配您的 RegEx。然后您所要做的就是将验证器映射到该输入。您仍然需要在服务器端进行验证,但您可能已经在这样做了。

【讨论】:

我过去曾使用此方法进行过验证,即使没有插件(插件更容易)。很遗憾,这不符合要求。【参考方案5】:

要做你想做的事,jquery caret plugin 是必需的。请注意,您需要从文件开头删除 cmets(或至少移动它们),否则代码开头的字节顺序标记将为 cause an error。

因此,您需要做的是捕获按键,在字符串中的正确位置插入字符,检查新字符串是否有效,然后显示新插入或不显示。我认为以下内容可以满足您的需求:

$(document).ready(function()
    var regex = new RegExp("^023-[0-9]0,7$");
    var caretpos;

    $('#number').keypress(function(event)
        // get the caret position
        caretpos = $(this).caret().start;
        //split the current value according to where the caret is
        valuestart = $(this).val().substring(0,caretpos);
        valueend = $(this).val().substring(caretpos);
        // insert the fired character into the string
        valuetocheck = valuestart + String.fromCharCode(event.which) + valueend;
        // check if the proposed new value passes the regex
        if (!regex.test(valuetocheck)) 
            // failed, prevent the character being shown
            event.preventDefault();
        
    );
);

我已经在最新版本的 FF、Chrome、Safari、Opera 和 IE9 中对此进行了测试。在 FF 和 Opera 中,光标按键在其他浏览器中像往常一样移动插入符号时被完全忽略,因此您可能需要添加一些代码以确保其行为一致。您可能还想添加一些代码来处理如果用户选择某些字符而不是单击输入会发生的情况。用于选择的 jquery caret 插件has usage examples。

【讨论】:

以上是关于使用 jQuery 防止 html 输入中的值的主要内容,如果未能解决你的问题,请参考以下文章

NuxtJs 从 jquery 更改的输入中获取值

防止多个选择相同的值

jQuery如何获取多个input输入框的值,并存放在一个数组中

怎样用jquery实现输入框只能输入大于零的数字? 两个输入框一个是宽度,一个是高度

html/css/js-如何利用jq来更改属性的值和获取属性的值

如果超出范围,防止 jQuery UI datepicker 更改文本字段的值