2017-07-31 40 views
1

这个问题部分依赖于jQuery内部工作的知识。jQuery风格重新应用效率

说我有一个垂直型溢出一个页面,允许用户向下滚动,下面的代码位在我的JS:

$(document).scroll(function() { 
    var y = $(document).scrollTop(); 
    if (y > 500) { 
     $("body").css("background-color", "red"); 
    } 
    else { 
     $("body").css("background-color", "blue"); 
    } 
}); 

这工作完全正常。但是,它可以这样修改:

var isRed = false; 
$(document).scroll(function() { 
    var y = $(document).scrollTop(); 
    if (y > 500) { 
     if (!isRed) { 
      $("body").css("background-color", "red"); 
      isRed = true; 
     } 
    } 
    else { 
     if (isRed) { 
      $("body").css("background-color", "blue"); 
      isRed = false; 
     } 
    } 
}); 

是否有理由选择第一个代码的第二位?如果我使用第一部分代码,那么每次滚动事件触发时,jQuery是否会一遍又一遍地应用样式?

我习惯了React的工作方式,只更新每个渲染改变的东西。 jQuery是否包含这样的功能?

这两段代码完成同样的事情。额外的isRed条件使得代码的第二版本更加冗长和复杂,但它可能会大大提高效率。它是否提供这样的好处?如果是这样,那么使用它而不是第一个是有意义的。

回答

1

有什么理由要选择代码的第二位在第一个?

是,如果你有滚动的性能问题。否则,它是否重新应用风格,没关系。

如果我使用第一位代码,jQuery是否每次都会在每次滚动事件触发时反复应用样式?

在每个滚动事件,当你做了$(body).css("background-color", "red"),jQuery的需要:

  1. 创建一个新的对象

  2. 确定您所传递的字符串是一个选择,而不是HTML

  3. 检查选择器是否包含jQuery扩展

  4. 查询的DOM的选择

  5. 生成结果的一个条目阵列

  6. 遍历一个进入阵列有效地这样做:

    element.style.backgroundColor = "red"; 
    

浏览器如果颜色与现有颜色相匹配,可能会忽略它。

如果您想在不使代码更复杂的情况下节省jQuery一些麻烦,请给它document.body使用,以便它可以跳过步骤2-4。您还可以简化代码公平一点:

$(document).scroll(function() { 
    var y = $(document).scrollTop(); 
    $(document.body).css("background-color", y > 500 ? "red" : "blue"); 
}); 

或者如果你想优化了整个呼叫:

(function() { // To avoid making `lastColor` a global 
    var lastColor; 
    $(document).scroll(function() { 
     var y = $(document).scrollTop(); 
     var color = y > 500 ? "red" : "blue"; 
     if (color !== lastColor) { 
      lastColor = color; 
      document.body.style.color = color; 
     } 
    }); 
})(); 

请注意,你不能比较colordocument.body.style.color,他们可能会(经常)以不同的格式。

1

是的。你的第一个将改变每秒几百次的CSS(如果滚动),第二个是一个简单而高效的去抖动器。

五月简单:

var isRed = false; 
$(document).scroll(function() { 
    if (isRed !== ($(document).scrollTop() > 500)) { 
     $("body").css("background-color", isRed?"blue":"red"); 
     isRed = !isRed; 
    } 
}); 

Try it