简体   繁体   中英

How do I increase efficiency/speed while using jQuery hover?

In a web application that I am writing, I have a series of divs which create a grid. The grid is X divs by Y divs, based on user input. Using jQuery hover function, I would like to change the background color of all surrounding divs within a certain distance. Basically, if I hover over a div, all divs within 4 rows and 4 columns away should also change their background color. I can get this functioning fine, but when the grid becomes 32 by 128 divs there is a real performance issue and the hover effect noticeably lags behind the mouse. I am almost certain that it is because of the large amount of similar divs within the DOM because the issue is not there when the grid is something like 30 by 30.

This is the basic structure of my html:

<div class="table_area">
    <div class="table_row" id="row-0">
        <div class="cap" data-row="0" data-column="0"></div>
        <div class="cap" data-row="0" data-column="1"></div>
        ...
    </div>
    <div class="table_row" id="row-1">
        <div class="cap" data-row="1" data-column="0"></div>
        <div class="cap" data-row="1" data-column="1"></div>
        ...
    </div>
    ...
</div>

To try to speed up the search of the DOM, I have added each row to an array. Thus, $('div.table_row[data-row="0"]') would be in arr[0] . So when a div in row 8 is hovered, I only check arr[4] through arr[12] for the necessary divs.

I would think that this would speed up the process quite a bit, since I am eliminating a substantial amount of the searching, but there is still a very noticeable lag in the hover.

Is there anything blatantly wrong with how I set this up? I am using the latest version of Chrome, if that matters.

Selecting by class name is native to the browser, whereas selecting by data within an element depends on looping within jQuery.

Use class names to label your rows and columns and your selector will be much faster.

If you add a class to each of the caps, you can then dynamically build a massive selector:

  var sel = "";
$(".cap").hover(function () {
    var row  = $(this).data("row");
    var col = $(this).data("column");
    sel = "";
    for(var i=row-2; i<=row+2; i++)
    {
      for(var j=col-2; j<=col+2; j++)
      {
        sel += ".r" + i + ".c" + j + ",";
      }
    }
  sel = sel.slice(0,-1);
  $(sel).css("background-color","blue");
},function () {
    $(sel).css("background-color","white");
  });
});

Example: http://jsbin.com/izeyal/38/edit

Since I was dynamically creating the rows and columns, I also added ids to each of the rows, which you can use for testing if you want by changing the selector generation code:

  sel += "#r" + i + "c" + j + ",";

For completeness, the code I used to generate the grid:

  for(i=0; i<128; i++)
  {
    var newRow = $('<div/>', {
    id: 'row-' + i
}).appendTo('.table_area');
    for (j=0; j<32; j++)
    {
      var rowid= "r" +i + "c" + j;
      $('<div/>', {id: rowid }).data("row",i).data("column",j).addClass("cap r" + i + " c" + j).appendTo(newRow);  
    }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM