emma
emma

Reputation: 343

How reduce delay in javascript / jquery change event?

I have five filters (multiple selects), which filter the data behind five visualisations in a dashboard. The filters have a JQuery change event, but the first line of code in this event takes half a second to happen. I don't understand why there's a delay. If I remove the code after the first line of code, the delay goes away. It's as though the code is not running in sequence.

The purpose of that first line of code is to make visible five "misty" (semi opaque) divs to obscure the graphics until the update code has run.

I'm using chosen.js on the selects but even when I remove chosen, there is still a delay. The filters are built dynamically. Here's the code that adds the change event:

  for (i=0; i<filters0Length; i++) {
  $("[id='"+filters[0][i]+"']").on('change',function(e,p){

    d3.selectAll("div.misty").style("visibility","visible");//make the fade divs appear - takes half a second

    if (!p) {
      for (var j=0; j<filters[0].length; j++) { filters[6][j] = []; filters[5][j].filterAll(); }

    } else {

      if (p.selected) {
        var tempIndex = filters[0].indexOf(e.target.id);//whether it's company, portfolio, industry or country
        filters[6][tempIndex].push(p.selected);//store this filter
        filters[5][tempIndex].filterFunction(function(d){ return filters[6][tempIndex].indexOf(d)!=-1; });
      }
      if (p.deselected) {
        var tempIndex = filters[0].indexOf(e.target.id);//whether it's company, portfolio, industry or country
        var tempIndex2 = filters[6][tempIndex].indexOf(String(p.deselected));

        filters[6][tempIndex].splice(tempIndex2,1);
        filters[5][tempIndex].filterAll();
        if (filters[6][tempIndex].length>0) { filters[5][tempIndex].filterFunction(function(d){ return filters[6][tempIndex].indexOf(d)!=-1; }); }
        window.portfolio_p = window.portfolio_p2;
      }

    }



    update();

  })
  }

If I remove the update commands, the code runs much quicker:

  for (i=0; i<filters0Length; i++) {
  $("[id='"+filters[0][i]+"']").on('change',function(e,p){

    d3.selectAll("div.misty").style("visibility","visible");//make the fade divs appear - takes half a second

  }

Upvotes: 0

Views: 329

Answers (1)

Roamer-1888
Roamer-1888

Reputation: 19288

Mmm, I have to agree you have an odd bug.

All I can suggest is pushing the filter manipulation into a later event thread.

You could contrive to use a Promise but window.setTimeout() is less expensive.

for(i=0; i<filters0Length; i++) {
    $("[id='"+filters[0][i]+"']").on('change', function(e, p) {
        d3.selectAll('div.misty').style('visibility', 'visible');
        window.setTimeout(function() {
            if (!p) {
                // etc...
            } else {
                // etc...
            }
            update();
        }, 0); // in practice the delay will be something like 15 ms.
    })
}

Upvotes: 1

Related Questions