问题与$(this).val().长度的铬 - 错误的值

jac*_*ack 1 jquery google-chrome

我在chrome中使用以下JQuery:$(this).val().length 这表示一个输入字段.现在在其他所有浏览器中都可以正常使用,但在Chrome中它有时会返回错误的值.假设我在输入字段中有3个字符,但alert($(this).val().length);会说4.

有谁知道为什么会发生这种情况并可能解决问题?

编辑:一些代码

$("#fieldset1 input[type=text]").keyup(function(e){
    if($(this).val().length == $(this).attr('maxlength')){
                if($(this).parent().children().last().attr('id') == $(this).attr("id")){
                    $(this).parent().next().find(':input').focus();
                }else{
                    $(this).next("input").focus();
                }
            }
});
Run Code Online (Sandbox Code Playgroud)

如果我注意到这种行为,我在第一次之后添加了警报.

edit2:把它放在JSFiddle:http://jsfiddle.net/QyyBV/

HTML:

<fieldset id ="test">
  <input type="text" id="1" maxlength="5" size="5"/>
  <input type="text" id="2" maxlength="5" size="5"/>
  <input type="text" id="3" maxlength="5" size="5"/>
  <input type="text" id="4" maxlength="5" size="5"/>
  <input type="text" id="5" maxlength="5" size="5"/>
</fieldset>
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

      $(document).ready(function() {

          $("#test input[type=text]").keydown(function(e){
            if(e.which == 8){
              if($(this).val().length == 0){
                $(this).prev().focus().val($(this).prev().val());
              }
            }
          });

          $("#test input[type=text]").keyup(function(e){


if($(this).val().length == $(this).attr('maxlength') ){
          if($(this).parent().children().last().attr('id') == $(this).attr("id")){
            $(this).parent().next().find(':input').focus();
          }else{
            $(this).next("input").focus();
          }
        }
      });

  });
Run Code Online (Sandbox Code Playgroud)

场景:我输入5次,然后再输入5次,我退格,直到第4个字段也是空的.有时(但并不总是)当我再次进入4 5时,尽管它应该跳到5 5,我仍会跳跃.但这并不总是发生.有时我需要再次执行此操作才能在Chrome中查看此问题.

T.J*_*der 9

更新4:

我不能用你的小提琴使用Chrome(对于Linux)来复制这个问题.

但是我注意到你正在使用keydown蒙面编辑的一个方面,但是keyup对于它的另一个方面.除非有一个非常好的理由使用keyup而不是keydown,我会同时使用keydown它们 - 尤其是因为然后按键重复与你正在创建的屏蔽编辑正常工作(例如,如果我按下'5'并按住它,我从我期望的字段到字段,而不是在第一个字段的末尾停止).

这是我稍微编辑的版本使用keydown.似乎工作正常(但是,你的原件也没有为我显示问题,可能是特定于操作系统):

$(document).ready(function() {

    $("#test input[type=text]").keydown(function(e){
        var $this = $(this),
            val = $this.val(),
            $prev,
            $parent;

        if(e.which == 8){
            if(val.length == 0){
                $prev = $this.prev();
                $prev.focus().val($prev.val());
            }
        }
        else if(val.length == $this.attr('maxlength') ){
            $parent = $this.parent();
            if($parent.children().last().attr('id') == $this.attr("id")){
                $parent.next().find(':input').focus();
            }else{
                $this.next("input").focus();
            }
        }

    });

});
Run Code Online (Sandbox Code Playgroud)

谁知道,也许这可以解决你所看到的奇怪问题.

偏离话题1:

我上面没有这样做,但是next()如果选择器没有匹配则会返回一个空的jQuery对象,你可以替换它

if($parent.children().last().attr('id') == $this.attr("id")){
    $parent.next().find(':input').focus();
}else{
    $this.next("input").focus();
}
Run Code Online (Sandbox Code Playgroud)

$next = $this.next("input");
if($next.length == 0) {
    $next = $parent.next().find(':input:first');
}
$next.focus();
Run Code Online (Sandbox Code Playgroud)

......(当然,$next用一个var顶部声明).这避免了需要$parent.children().last().attr('id') == $this.attr("id"),这是必要的工作.您可以向退格添加等效功能:

if(val.length == 0){
    $prev = $this.prev();
    if($prev.length == 0) {
        $prev = $this.parent().prev().find(':input:last');
    }
    $prev.focus().val($prev.val());
}
Run Code Online (Sandbox Code Playgroud)

实例.FWIW.


题外话2:这些ID你给的字段在你的榜样(1,2,等),同时有效的HTML标识,是与CSS选择使用无效.CSS中的ID不能以数字开头(或其他一些内容,请参阅链接了解详情).我提到这个是因为我们在jQuery中经常使用CSS选择器...


偏离主题3:反复呼叫$(this)使您的浏览器比以前更加努力.每次执行此操作时,jQuery最终会执行两次函数调用和内存分配.这可能不是问题,但很少有理由不将结果缓存在局部变量中,例如var $this = $(this);.



以前的答案更新:


更新3:

你偶尔会提到它,并且你提到了退格,但引用的代码对退格没有任何作用.实际上,一个简洁,自足的功能性示例将是发现这一点的关键.听起来像是事件与焦点顺序的浏览器差异(因为你正在修改焦点),但......

更新2:

重新评论它是一个keyup处理程序,我仍然没有看到这种行为:

$('#theField').keyup(function() {
  if ($(this).val().length == $(this).attr("maxlength")) {
    display("Field is at maximum, length = " +
            $(this).val().length);
  }
  else {
    display("Field is not at maximum, length = " +
            $(this).val().length);
  }
});
Run Code Online (Sandbox Code Playgroud)

实时复制

请注意,您最新发布的代码(截至撰写本文时)存在语法错误(应该结束});,而不仅仅是};),但我猜这是复制粘贴的副作用.

建议将代码削减到最低限度,将其发布到JSBinjsFiddle或类似代码,我们可以帮助您找到问题所在.


更新1:

我的猜测(更多上下文会有所帮助!那个事件处理程序是什么?)你是在keypress处理程序中这样做的.截至keypress事件,该角色尚未(尚未)添加到该字段中.实例:

$('#theField').keypress(function() {
  if ($(this).val().length == $(this).attr("maxlength")) {
    display("Field is at maximum, length = " +
            $(this).val().length);
  }
  else {
    display("Field is not at maximum, length = " +
            $(this).val().length);
  }
});

function display(msg) {
  $('<p/>').html(msg).appendTo(document.body);
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这是跨浏览器的可靠行为,所以如果你真的只在Chrome上看到,也许你正在使用另一个我没有多少经验的活动.例如,以上在Firefox中很好.

在任何情况下,如果问题是事件发生得太早以至于您正在尝试做什么,您可以轻松地推迟它:

$('#theField').keypress(function() {
  var $this = $(this);
  setTimeout(function() {
    if ($this.val().length == $this.attr("maxlength")) {
      display("Field is at maximum, length = " +
              $this.val().length);
    }
    else {
      display("Field is not at maximum, length = " +
              $this.val().length);
    }
  }, 0);
});
Run Code Online (Sandbox Code Playgroud)

实例


原始答案:

我怀疑该领域确实有四个角色.当然,它工作正常,在Chrome中,与这个活生生的例子:

HTML:

<form>
    <input type='text' id='theField' value='123'>
</form>
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

display('Length is ' + $('#theField').val().length);

function display(msg) {
  $('<p/>').html(msg).appendTo(document.body);
}
Run Code Online (Sandbox Code Playgroud)