如何使这个冗余的JavaScript更有效?

时间:2014-01-03 01:16:19

标签: javascript jquery ruby-on-rails

我正在使用jQuery来为Rails表单调整验证。下面的脚本工作得很好,但我知道有一种方法可以通过声明字段名称和错误消息字符串然后使脚本在列表中运行来提高效率,但我还不够复杂,无法编写。

重写它的正确方法是什么?

$( '.sendername' ).blur(function() {
  if ($('.sendername').val() == "") {
      $('.sendername-err').text('This field is required.');
      $('.sendername').addClass('invalid');
  } else {
    $('.sendername-err').text('');
    $('.sendername').removeClass('invalid');
  }
});

$( '.email' ).blur(function() {
  if ($('.email').val() == "") {
      $('.email-err').text('You've forgotten this.');
      $('.email').addClass('invalid');
  } else {
    $('.email-err').text('');
    $('.email').removeClass('invalid');
  }
});

$( '.subject' ).blur(function() {
  if ($('.subject').val() == "") {
      $('.subject-err').text('Please enter a value.');
      $('.subject').addClass('invalid');
  } else {
    $('.subject-err').text('');
    $('.subject').removeClass('invalid');
  }
});

$( '.message' ).blur(function() {
  if ($('.message').val() == "") {
      $('.message-err').text('Zero characters is too short.');
      $('.message').addClass('invalid');
  } else {
    $('.message-err').text('');
    $('.message').removeClass('invalid');
  }
});

我问,因为我想了解如何更好地编写javascript。类似的情况经常出现,它让我香蕉这样做。

6 个答案:

答案 0 :(得分:2)

我会遍历所有这些根名称,并将所有代码放在那里。

另外,不要忘记在you've

中逃避撇号

正如Pointy指出的那样,在你的jQuery事件处理程序中,this值将被设置为有问题的元素。如果-err元素始终位于相关元素的旁边,则可以通过替换

进一步简化
$(name + '-err').text('You\'ve forgotten this.');

$el.next().text('You\'ve forgotten this.');

['.email', '.subject', '.message'].forEach(function(name){
    $(name).blur(function() {
      var $el = $(this);
      if ($el.val() == "") {
          $(name + '-err').text('You\'ve forgotten this.');
          $el.addClass('invalid');
      } else {
          $(name + '-err').text('');
          $el.removeClass('invalid');
      }
    });
});

答案 1 :(得分:2)

您的标记看起来不够一致,但您可以创建更一致的命名标准(使所有后缀和前缀相同 - 例如,始终使用-name或从不使用它),然后使用函数:< / p>

function setup_field(name, message) { 
  $( '.'+name+'-name' ).blur(function() {
    if ($('.'+name+'-name').val() == "") {
        $('.'+name+'-err').text(message);
        $('.'+name+'-name').addClass('invalid');
    } else {
      $('.'+name+'-err').text('');
      $('.'+name+'-name').removeClass('invalid');
    }
  });
}

然后你只需为每个字段调用它:

setup_field('sender', 'This field is required.');
setup_field('email', "You've forgotten this.");
setup_field('subject', 'Please enter a value.');
setup_field('message', 'Zero characters is too short.');

当然,重点是使用一个功能。您甚至可以使其足够灵活,允许您通过向函数签名添加更多变量来以不同的方式定义每个类。 setup_field(field_class, err_class, message),然后在适当的时候将这些变量插入上面的函数中。但这会使你的设置区域更加冗长。

答案 2 :(得分:2)

var dataObj = {
        "sender": "This field is required.",
        "email": "You've forgotten this.",
        "subject": "Please enter a value.",
        "message": "Zero characters is too short."
    },
    N = "-name",
    E = "-err",
    D = ".",
    I = "invalid",
    fn = function(el) {
        $( D + el + N ).blur(function() {
            var $el = $(D + el + N);
            if ($el.val() === "") {
                $(D + el + E).text(dataObj[el]);
                $el.addClass(I);
            } else {
                $(D + el + N + E).text('');
                $el.removeClass(I);
            }
        });
    };

for(var el in dataObj) {
    fn(el);
}

答案 3 :(得分:1)

我会这样做:

var CSS_CLASS_INVALID = 'invalid';
function newCallbackForFieldAndErrorWithMessage(item) {
    return function () {
        var error_message = item.error_message,
            $field = $(item.field_selector),
            $error = $(item.error_selector),
            text;
        if ($field.val() == "") {
            text = error_message;
            $field.addClass(CSS_CLASS_INVALID);
        } else {
            text = '';
            $field.removeClass(CSS_CLASS_INVALID);
        }
        $error.text(text);
    };
}
var fields = [{
    field_selector: '.sender-name',
    error_selector: '.sender-name-err',
    error_message: 'This field is required.'
}, {
    field_selector: '.email',
    error_selector: '.email-err',
    error_message: 'You\'ve forgotten this.'
}, {
    field_selector: '.subject',
    error_selector: '.subject-err',
    error_message: 'Please enter a value.'
}, {
    field_selector: '.message',
    error_selector: '.message-err',
    error_message: 'Zero characters is too short.'
}];

$.each(fields, function (index, item) {
    $(item.field_selector).blur(newCallbackForFieldAndErrorWithMessage(item));
});

您可以在此处测试代码:http://jsfiddle.net/dragulceo/8dPPE/

答案 4 :(得分:0)

好的,用变量标签替换所有$('。sender-name')。

var Names = $('。sender-name'); 然后改用变量。查找dom树中的元素需要一些时间用于浏览器。

答案 5 :(得分:0)

我建议使用更流畅的验证技术(声明性与程序性)。请参阅我的回答here