代码审查?有没有办法更好地写这个?

时间:2016-07-03 08:58:31

标签: javascript jquery optimization

我有一些代码。

$(this).find('.change--button__approve').click(function(){
    if ($(this).hasClass('disabled')) {
      return false;
    } else {
      $(thisChange).attr('data-type', 'approved').attr('data-changeRule', 'once');
      $(this).parent().parent().next().find('p').attr('class','approved').addTemporaryClass('bounceIn', 500);
      $(this).parent().parent().next().find('.changeStatus').text('approved for this document');
    }
  });
  $(this).find('.change--button__approveAlways').click(function(){
    if ($(this).hasClass('disabled')) {
      return false;
    } else {
      $(thisChange).attr('data-type', 'approved').attr('data-changeRule', 'always');
      $(this).parent().parent().next().find('p').attr('class','approved').addTemporaryClass('bounceIn', 500);
      $(this).parent().parent().next().find('.changeStatus').text('approved for every document');
    }
  });;
  $(this).find('.change--button__reject').click(function(){
    if ($(this).hasClass('disabled')) {
      return false;
    } else {
      $(thisChange).attr('data-type', 'rejected').attr('data-changeRule', 'once');
      $(this).parent().parent().next().find('p').attr('class','rejected').addTemporaryClass('bounceIn', 500);
      $(this).parent().parent().next().find('.changeStatus').text('rejected for this document');
    }
  });;
  $(this).find('.change--button__rejectAlways').click(function(){
    if ($(this).hasClass('disabled')) {
      return false;
    } else {
      $(thisChange).attr('data-type', 'rejected').attr('data-changeRule', 'always');
      $(this).parent().parent().next().find('p').attr('class','rejected').addTemporaryClass('bounceIn', 500);
      $(this).parent().parent().next().find('.changeStatus').text('rejected for every document');
    }
  });;

由于代码的重复性,我认为必须有更好的方法来编写它。我还是初学者,所以我很想知道如何写这个更干净/更好。

谢谢!

2 个答案:

答案 0 :(得分:2)

以下是优化代码:

var _this = $(this);

_this.find('.change--button__approve').click(function() {
  var sibling, _this = $(this);

  if (_this.hasClass('disabled')) {
    return false;
  } else {
    $(thisChange).attr('data-type', 'approved').attr('data-changeRule', 'once');
    sibling = _this.parent().parent().next();
    sibling.find('p').attr('class','approved').addTemporaryClass('bounceIn', 500);
    sibling.find('.changeStatus').text('approved for this document');
  }
});

_this.find('.change--button__approveAlways').click(function() {
  var sibling, _this = $(this);

  if (_this.hasClass('disabled')) {
    return false;
  } else {
    $(thisChange).attr('data-type', 'approved').attr('data-changeRule', 'always');
    sibling = _this.parent().parent().next();
    sibling.find('p').attr('class','approved').addTemporaryClass('bounceIn', 500);
    sibling.find('.changeStatus').text('approved for every document');
  }
});

_this.find('.change--button__reject').click(function() {
  var sibling, _this = $(this);

  if (_this.hasClass('disabled')) {
    return false;
  } else {
    $(thisChange).attr('data-type', 'rejected').attr('data-changeRule', 'once');
    sibling = _this.parent().parent().next();
    sibling.find('p').attr('class','rejected').addTemporaryClass('bounceIn', 500);
    sibling.find('.changeStatus').text('rejected for this document');
  }
});

_this.find('.change--button__rejectAlways').click(function() {
  var sibling, _this = $(this);

  if (_this.hasClass('disabled')) {
    return false;
  } else {
    $(thisChange).attr('data-type', 'rejected').attr('data-changeRule', 'always');
    // Store into a variable to optimize execution speed
    sibling = _this.parent().parent().next();
    sibling.find('p').attr('class','rejected').addTemporaryClass('bounceIn', 500);
    sibling.find('.changeStatus').text('rejected for every document');
  }
});

如您所见,主要问题是在两个同时行上使用$(this).parent()。parent()。next(),这会导致速度问题。通过将其存储在局部变量中,该函数链不会运行两次,并且在使用后删除局部变量。

第二个问题(不太重要)是重复使用$(this),每次使用它时都需要创建一个jQuery实例。通过将其存储在局部变量_this中,您可以根据需要随时使用,而不会导致需要时间的实例化。

编辑:另一个更复杂但更好的方法是:

var _this = $(this);

var details = {
  'approve': ['once', 'approved', 'approved for this document'],
  'approveAlways': ['always', 'approved', 'approved for every document'],
  'reject': ['once', 'rejected', 'rejected for this document'],
  'rejectAlways': ['always', 'rejected', 'rejected for every document']
}, keys = Object.keys(details);

for(var i = 0; i < keys.length; i++)
  // Create a lambda function to use local variable 'scope'
  (function(scope) {
    // Here is the content of 'scope' :
    // scope[0] : value of 'data-changeRule' ('once' or 'always')
    // scope[1] : value of 'data-type' and 'class' ('approved' or 'rejected')
    // scope[2] : message to display 'approved for this document'...
    _this.find('.change--button__' + scope[3]).click(function() {
      var sibling, _this = $(this);

      if (_this.hasClass('disabled')) {
        return false;
      } else {
        $(thisChange).attr('data-type', scope[1]).attr('data-changeRule', scope[0]);
        sibling = _this.parent().parent().next();
        sibling.find('p').attr('class', scope[1]).addTemporaryClass('bounceIn', 500);
        sibling.find('.changeStatus').text(scope[2]);
      }
    });
  }).call(this, details[keys[i]].concat([keys[i]])); // Call the lambda function with its informations

请注意,此代码未尽可能优化,但如果我优化它将会很难看。

编辑2:我认为,这是更快更好的方法:

var _this = $(this),
    keys = ['approve', 'approveAlways', 'reject', 'rejectAlways'];

for(var i = 0; i < keys.length; i++)
  // Create a lambda function to use local variable 'scope'
  (function(name) {
    _this.find('.change--button__' + name).click(function() {
      var sibling, _this = $(this),
          approve = (name.indexOf('approve') !== -1 ? 'approved' : 'rejected'), // Is the button an approving or rejecting button ?
          always  = (name.indexOf('Always') !== -1); // Is the button setting always or only for THIS document ?

      if (_this.hasClass('disabled')) {
        return false;
      } else {
        $(thisChange).attr('data-type', approve).attr('data-changeRule', (always ? 'always' : 'once'));
        sibling = _this.parent().parent().next();
        sibling.find('p').attr('class', approve).addTemporaryClass('bounceIn', 500);
        sibling.find('.changeStatus').text(approve + ' for ' + (always ? 'every' : 'this') + ' document');
      }
    });
  }).call(this, keys[i]); // Call the lambda function with its informations

只存储了几个字符串,您的函数_this.find('.change--button__...').click(仅被写入一次并由循环多次运行。如果要添加按钮,只需在数组keys中添加其名称即可。

我希望我帮助过你:)

答案 1 :(得分:-1)

尝试存储你的字符串

'.change--button__approve', '.change--button__approveAlways',...

在像

这样的数组中
var strings = new Array('.change--button__approve', '.change--button__approveAlways', '.change--button__reject','.change--button__rejectAlways');

并使用for循环来避免代码重复:

for(int i=0; i<strings.length;i++){
    $(this).find(strings[i]).click(function(){
        ... 
    }
}

你的更改字符串'once'/'always'也需要一个数组,如果这基本上有效的话 (不完全确定)