Javascript JQuery:如何缓存DOM?

Javascript JQuery:如何缓存DOM?,javascript,jquery,optimization,Javascript,Jquery,Optimization,我使用Firefug评测了我的web应用程序,发现以下函数在每次用户访问时都会被调用,并且需要被调用数百次。所以我想优化它,因为Firebug说它使用了最多的资源/次数 function highlightChildDiv(parentDiv) { /* find the closest (hlisting) home listing to the middle of the scrollwindow & highlight */ var scrollElemP

我使用Firefug评测了我的web应用程序,发现以下函数在每次用户访问时都会被调用,并且需要被调用数百次。所以我想优化它,因为Firebug说它使用了最多的资源/次数

function highlightChildDiv(parentDiv) {

    /* find the closest (hlisting) home listing to the middle of the scrollwindow & highlight */    
    var scrollElemPos = parentDiv.offset();
    var highlightDiv = $(document.elementFromPoint(
        scrollElemPos.left + parentDiv.width()  / 2,
        scrollElemPos.top  + parentDiv.height() / 2)
    ).closest('#parentDiv div.childClass');

    if (highlightDiv.hasClass("HighlightRow")) { 
        return; // if the div is already highlighted, return
    } else {
        $('#parentDiv div.childClass').removeClass("HighlightRow");
        highlightDiv.addClass('HighlightRow');
    }
}
在我看来,最未优化的语句之一是
.closest(“#parentDiv div.childClass”),但我确信还有其他需要改进的地方


问题:鉴于此功能在每次用户访问时都会运行数百次,有没有人对我如何优化上述代码有任何JQuery性能提示。

首先,消除
if
子句中的死语句

if (!highlightDiv.hasClass("HighlightRow")) {  
    $('#parentDiv div.childClass').removeClass("HighlightRow"); 
    highlightDiv.addClass('HighlightRow'); 
} 
在选择器
#parentDiv div.childClass
中,能否保证div将是#parentDiv的直接后代?在这种情况下:

.closest('#parentDiv>div.childClass');

您已经有了
parentDiv
。我猜这是一个DOM对象,因此您可以执行以下操作:

$(parentDiv).children("div.childClass")
只需隐藏当前高亮显示的DIV:

$('#parentDiv div.HighlightRow').removeClass("HighlightRow");

首先,消除
if
子句中的死语句

if (!highlightDiv.hasClass("HighlightRow")) {  
    $('#parentDiv div.childClass').removeClass("HighlightRow"); 
    highlightDiv.addClass('HighlightRow'); 
} 
在选择器
#parentDiv div.childClass
中,能否保证div将是#parentDiv的直接后代?在这种情况下:

.closest('#parentDiv>div.childClass');

您已经有了
parentDiv
。我猜这是一个DOM对象,因此您可以执行以下操作:

$(parentDiv).children("div.childClass")
只需隐藏当前高亮显示的DIV:

$('#parentDiv div.HighlightRow').removeClass("HighlightRow");

我猜这是最不理想的路线:

$('#parentDiv div.childClass').removeClass("HighlightRow");
您应该对其进行分析以确保(在调用之外创建一个日期对象,并在每次调用之前和之后输出getTime()值)

在这里,您要求jQuery迭代与该选择器匹配的所有DOM元素并删除该类。如果有1000行,jQuery将需要对每一行进行互操作,以查看是否需要删除一个类。啊。以下是已删除的查找:

// namespace scoped cache
var Hash_$_Cache = {
  $parentDiv : $('#parentDiv'),
  $tgt_row   : $([])  // empty jq object to start
};

// find the closest (hlisting) home listing to the middle of 
// the scrollwindow and highlight
//    
var highlightChildDiv = function (parentDiv){
  var
    scrollElemPos = parentDiv.offset(),
    $tgt_row
    ;

  $tgt_row = $(document.elementFromPoint(
    scrollElemPos.left + parentDiv.width()  / 2,
    scrollElemPos.top  + parentDiv.height() / 2)
  ).closest('#parentDiv div.childClass')
  ;

  // bail if row is already highlighted
  if ($tgt_row.hasClass('HighlightRow')){ return; }

  Hash_$_Cache.$tgt_row.removeClass('HighlightRow');
  $tgt_row.addClass('HighlightRow');

  // save highlighted row for later
  Hash_$_Cache.$tgt_row = $tgt_row; // store new row in cache
};

希望有帮助

我猜这是最不理想的路线:

$('#parentDiv div.childClass').removeClass("HighlightRow");
您应该对其进行分析以确保(在调用之外创建一个日期对象,并在每次调用之前和之后输出getTime()值)

在这里,您要求jQuery迭代与该选择器匹配的所有DOM元素并删除该类。如果有1000行,jQuery将需要对每一行进行互操作,以查看是否需要删除一个类。啊。以下是已删除的查找:

// namespace scoped cache
var Hash_$_Cache = {
  $parentDiv : $('#parentDiv'),
  $tgt_row   : $([])  // empty jq object to start
};

// find the closest (hlisting) home listing to the middle of 
// the scrollwindow and highlight
//    
var highlightChildDiv = function (parentDiv){
  var
    scrollElemPos = parentDiv.offset(),
    $tgt_row
    ;

  $tgt_row = $(document.elementFromPoint(
    scrollElemPos.left + parentDiv.width()  / 2,
    scrollElemPos.top  + parentDiv.height() / 2)
  ).closest('#parentDiv div.childClass')
  ;

  // bail if row is already highlighted
  if ($tgt_row.hasClass('HighlightRow')){ return; }

  Hash_$_Cache.$tgt_row.removeClass('HighlightRow');
  $tgt_row.addClass('HighlightRow');

  // save highlighted row for later
  Hash_$_Cache.$tgt_row = $tgt_row; // store new row in cache
};

希望有帮助

我更喜欢使用以下方法:

或者,在此实现中,您可以使用方法替换DOM对象:

var myNS = {
    myEventHandler: function(event){
        this.DOM.$el.doSomething();
    },
    cacheDOM: function(){
        return {
             $el: $("#matrix")
        };
    },
    initialize: function(){
        this.DOM = this.cacheDOM();
    }
};

我更喜欢使用以下方法:

或者,在此实现中,您可以使用方法替换DOM对象:

var myNS = {
    myEventHandler: function(event){
        this.DOM.$el.doSomething();
    },
    cacheDOM: function(){
        return {
             $el: $("#matrix")
        };
    },
    initialize: function(){
        this.DOM = this.cacheDOM();
    }
};

只是一个小问题:从长远来看,将事物称为相对的名称,如“父”和“子”可能不那么容易理解:)我更改了名称,以帮助人们在我的应用程序执行的上下文中更好地理解我的代码只是一个小问题:将事物称为相对的名称,如“父”和“子”从长远来看,可能没有那么可读性:)我更改了名称,以帮助人们在我的应用程序正在执行的上下文中更好地理解我的代码。你说的“直系后代”是什么意思。如果我的HTML是“父->中->子”会发生什么。使用“#parentDiv>div.childClass”是否仍然比“#parentDiv div.childClass”更合适、更快?不,我是说#parent>#middle比#parent#middle快#家长>#孩子在你的例子中不起作用。你说的“直系后代”是什么意思。如果我的HTML是“父->中->子”会发生什么。使用“#parentDiv>div.childClass”是否仍然比“#parentDiv div.childClass”更合适、更快?不,我是说#parent>#middle比#parent#middle快#父项>#子项在您的示例中不起作用。