Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使这个冗余javascript更高效?_Javascript_Jquery_Ruby On Rails - Fatal编程技术网

如何使这个冗余javascript更高效?

如何使这个冗余javascript更高效?,javascript,jquery,ruby-on-rails,Javascript,Jquery,Ruby On Rails,我正在使用jQuery对Rails表单进行ajaxify验证。下面的脚本工作得很好,但我知道有一种方法可以使它更高效,方法是声明字段名和错误消息字符串,然后让脚本在列表中运行,但我还没有足够的技巧来编写它 重写它的正确方法是什么 $( '.sendername' ).blur(function() { if ($('.sendername').val() == "") { $('.sendername-err').text('This field is required.');

我正在使用jQuery对Rails表单进行ajaxify验证。下面的脚本工作得很好,但我知道有一种方法可以使它更高效,方法是声明字段名和错误消息字符串,然后让脚本在列表中运行,但我还没有足够的技巧来编写它

重写它的正确方法是什么

$( '.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。类似的情况经常出现,这样做让我感到非常激动。

好的,用变量替换所有的$('.sender name')

变量名称=$('.sender name');
然后改用变量。对于浏览器来说,在dom树中查找元素需要一些时间。

我建议使用更流畅的验证技术(声明性验证与过程性验证)。请看我的答案。

我将循环遍历所有这些根名称,并将所有代码放在其中

另外,不要忘记在
您已经

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

$(name + '-err').text('You\'ve forgotten this.');



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

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.');
当然,重点是使用函数。您甚至可以通过向函数签名添加更多变量,使其足够灵活,允许您以自己喜欢的方式定义每个类<代码>设置字段(字段类、错误类、消息),然后在适当的情况下将这些变量插入上述函数。但这会使您的设置区域更加冗长。

我会这样做:

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);
}
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));
});

您可以在此处测试代码:

如果您想查看代码,请询问我不知道的问题。我想我会成为一名常客。谢谢当然,您希望利用jQuery确保事件中涉及的实际元素通过
this
可用这一事实。我不知道如何插入不同的错误消息,但这帮助我大致了解了如何将一组函数组合成一组。非常感谢。这正是我的想法。还有,你说得对,我有一个打字错误,我已经改正了。非常感谢。起初这很难理解,但现在我明白发生了什么。我会在不使用NEDI的情况下使用它,只输入值。谢谢-这有助于理解如何做到这一点。我在“提交”上使用本机Rails验证,我还希望在blur上对必填字段进行ajax验证。您的解决方案是一个很好的解决方案,我可以对其进行修改-我正在复制它,但在本例中,我想学习如何将一组类似的函数浓缩为一个。当您使用声明式方法时,您有一个不变的代码库和许多要验证的控件属性。添加更多控件时,代码量不会增加。这实际上是把一堆相似的函数浓缩成一个。
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);
}
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));
});