如何使这个功能更有效,包含3个循环?

时间:2014-05-06 00:38:13

标签: javascript jquery

我创建了这个函数,它循环遍历甘特图中代表任务的一堆元素。每个任务都有一个"链接"和属性" id"和" pre"。

"预"代表前任的任务。

该函数用于计算每个任务前任的内容,然后调用另一个在它们之间绘制箭头的函数。

我能想到如何做到这一点的唯一方法是首先创建一个任务数组然后循环遍历该数组并获得每个任务的前任,再次遍历任务数组并找到id与前任和然后调用draw函数,如下所示。

但这导致了三个循环,其中一个循环在另一个循环中,如下所示,我不能帮助以为会有更有效的方法来做同样的事情吗?我的应用程序很慢,这只会让它变得更糟。

有人能建议一种重写此功能的方法更有效吗?

P.S应用程序很大,为此做一个jsfiddle,代码是相当自我解释。

 //Adds relationship link arrows between tasks
function add_arrows()
{
    var ttask = new Array();
    var pre = 0;

    //loop through all task elements with the class link and add them to an array
    $(".link").each(function(i) 
    {
        ttask[i] = $(this);
    });

    //loop through the array if tasks
    for (var i=0, l=ttask.length; i < l; i++ ) 
    {
        //if its not the first task get its predecessor value
        if(i != 0)
        {
            pre = ttask[i].attr('pre');
        }
        //loop through the array of tasks again and get the task with an id that matches the predecessor value
        for (var j=0, k=ttask.length; j < k; j++ ) 
        {
            if(ttask[j].attr('id') == pre)
            {
                var predecessor = ttask[j];
            }
        }
        //if its not the first task, draw a link between the predecessor and current task
        if(i != 0)
        {
            drawlink(predecessor, ttask[i], ttask[i].attr('link')); //function takes: predecessor, current task, link type
        }
    }
}

在下面的建议之后,到目前为止看起来效率最高?除非有人能说出为什么另一种方法在计算上更好?

function add_arrows(){
   $(".link").each(function(i) {
      var $el = $(this);
      if(i) drawlink($('#' + $el.attr('pre')), $el, $el.attr('link'));
   });
 }

3 个答案:

答案 0 :(得分:2)

当然它只是查找具有前驱的所有元素(根据您的代码判断,具有pre属性)并添加指向由其link属性指示的元素的链接。 / p>

类似的东西:

 $('[pre]').each(function(i,el){
        var self = $(el),
        link = self.attr('link'),
        predecessor = $('#' + link);
        if (predecessor.length)
        {
            //i.e. A predecessor has been found, assuming that #0 is not an element
            drawlink(predecessor, self , link );
         }
    });

答案 1 :(得分:0)

试试这个:

function add_arrows(){
$(".link").each(function(i) {
    var predecessor = (typeof ($(this).attr('pre')) !== "undefined") ? $("#"+($(this).attr('pre'))) : null;
    drawlink(predecessor, $(this), $(this).attr('link'));
});
}

答案 2 :(得分:0)

似乎具有“link”类的元素可以具有“pre”属性,该属性指定它们是其前身的元素。据推测,每个元素只有一个前身。每个link元素也都有一个link属性。

drawlink 函数有三个参数:前趋,元素及其链接属性值。

获取带有类链接的元素列表,然后迭代它并为每个具有非空前属性的元素调用 drawlink

function joinPredecessors() {
  $('.link').each(function() {
    var el = $(this);
    var pre = el.attr('pre');

    // Only draw a line if the element has a predecessor
    if (pre != '' && pre != null) {
      drawlink($('#' + pre), el, el.attr('link'));
    }
  });
}

鉴于你要求“高效”,上面简洁但可能很慢,一个普通的javscript方法是:

function joinPredecessors() {
  // Work with plain JS and DOM
  var links = document.querySelectorAll('.link');
  var el, pre;

  for (var i=0, iLen=links.length; i<iLen; i++) {
    el = links[i];
    pre = el.getAttribute('pre');

    if (pre != '' && pre != null) {
      // Pass jQuery objects
      drawlink($('#' + pre), $(el), el.getAttribute('link'));
    }
  }
}

这几乎不再是代码和about twice as fast,至少在IE和移动版Safari中。