Ненадежный тест регулярных выражений javascript в Firefox и Chrome - PullRequest
6 голосов
/ 20 июля 2010

Я сталкиваюсь со странной проблемой регулярных выражений javascript в Firefox 3.6 и Chrome 6 dev.Я работаю над огромным веб-сайтом для ввода форм, который имеет некоторую базовую проверку javascript с использованием jQuery.

$(document).ready(function() {
  $("tr[id^='" + BaseRowId + "rid']").each(function(){obj.WireRowEvents(this);});
}
var obj = {
  "WireRowEvents": function(row) {
    $("input[id$='Orgn']").blur(function() { obj.ValidateOrgn(this); }).blur();
    $("input[id$='Prog']").blur(function() { obj.ValidateProg(this); }).blur();
  },
  "ValidateOrgn": function(orgnId) { // ValiadateProg is the same as this
    var orgn = $(orgnId);            // function except it checks for a
    if (orgn.length == 0)            // length of 4 instead of 5.
      return;
    var orgnValue = orgn.val();
    if (orgnValue.length != 5) {
      if (orgnValue.length > 0) {
        orgn.addClass("invalid");
      } else {
        orgn.removeClass("invalid");
      }
    } else {
      if (/\d{5}/g.test(orgnValue)) { // This is the problem area
        orgn.removeClass("invalid");  // The above line is '/\d{4}/g' for prog.
      } else {
        orgn.addClass("invalid");
      }
    }
  }
}

Использование вышеуказанного javascript (упрощено только функции ready и WireRowEvents, но метод ValidateOrgnполностью неповрежден. Как видите, единственные требования, предъявляемые к Orgn, должны быть длиной 5 цифр, а Prog - длиной 4 цифры. В Internet Explorer 7 и 8, а также в Safari 4.0.4 работает приведенный выше код.как и должно быть.

В Firefox и Chrome при загрузке страницы Orgn и Prog помечаются как недействительные, но только с правой стороны. Полная строка содержит два входа Orgn и два входа Prog (с разными идентификаторами, но заканчивающимися наOrgn и Prog.) Левая сторона отображается, как и должно быть, но правая сторона является «недействительной».

http://www.gibixonline.com/media/so/jquery-regex-initial.png

Самое приятное то, что вы можете щелкнуть в текстовом поле и нажатьвернуться назад и иногда (не на 100%) он будет проверен правильно.

http://www.gibixonline.com/media/so/jquery-regex-clicking.png

При переходе через функции ValidateOrgn и ValidateProg в Firebug строка if (/\d{5}/g.test(orgnValue)) возвращает falseчто заставляет его добавить класс CSS invalid.Если в этот момент я копирую ту же самую строку и вставляю ее в консоль, возвращается true, как и ожидалось.Опять же, щелкнув и щелкнув, вы переключитесь между действительным и недействительным состояниями.

В Internet Explorer и Safari это работает должным образом, и я не могу воспроизвести проблему там.

http://www.gibixonline.com/media/so/jquery-regex-correct.png

Обновление

Это действительно была проблема глобального флага.Благодаря комментарию Пойнти мне также удалось упростить вызов функции (он был объединен и помечен для очистки в любом случае).Новый метод теперь:

"ValidateOrgn": function (orgnId) {
  var orgn = $(orgnId);
  if (orgn.length == 0)
  return;

  // I don't want to mark it invalid if it's blank.
  if (orgn.val().length > 0) {
    if (/^\d{5}$/.test(orgn.val())) {
      orgn.removeClass("invalid");
    } else {
      orgn.addClass("invalid");
    }
  } else {
    orgn.removeClass("invalid");
  }
}

Ответы [ 2 ]

3 голосов
/ 20 июля 2010

Возможно, попробуйте поместить свое регулярное выражение в отдельную переменную, например:

  //...
  var re = /^\d{5}$/; // using Pointy's comment, which I think is well-advised

  if (re.test(orgnValue)) { // This is the problem area
    orgn.removeClass("invalid");  // The above line is '/\d{4}/g' for prog.
  } else {
    orgn.addClass("invalid");
  }
  //...
2 голосов
/ 20 июля 2010

Это известная проблема с некоторыми браузерами при использовании объекта регулярного выражения, вызванная свойством lastIndex. Вы можете легко воспроизвести его:

var r = /\d{5}/g;

alert(r.test('12345')); //true
alert(r.test('12346')); //false

В вашем случае регулярное выражение кэшируется, и вы видите тот же эффект. Простое решение - сбросить регулярное выражение lastIndex: r.lastIndex = 0 или, как предлагается, использовать регулярное выражение, если это не проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...