Javascript 如何使此函数更有效,包含3个循环?

Javascript 如何使此函数更有效,包含3个循环?,javascript,jquery,Javascript,Jquery,我创建了这个函数,它通过甘特图中表示任务的一组元素进行循环。每个任务都有“link”类和“id”和“pre”属性 “pre”表示任务前置 该函数用于计算每个任务的前置任务是什么,然后调用另一个函数,在它们之间画一个箭头 我能找到的唯一方法是首先创建一个任务数组,然后循环遍历该数组并获得每个任务的前置任务,再次循环遍历任务数组并找到id与前置任务匹配的任务,然后调用draw函数,如下所示 但这导致了三个循环,一个循环在另一个循环中,如下所示,我不禁想,还有更有效的方法来做同样的事情吗?我的应用程序

我创建了这个函数,它通过甘特图中表示任务的一组元素进行循环。每个任务都有“link”类和“id”和“pre”属性

“pre”表示任务前置

该函数用于计算每个任务的前置任务是什么,然后调用另一个函数,在它们之间画一个箭头

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

但这导致了三个循环,一个循环在另一个循环中,如下所示,我不禁想,还有更有效的方法来做同样的事情吗?我的应用程序虽然很慢,但这只会让情况变得更糟

有人能提出一种更有效地重写此函数的方法吗

另外,应用程序太大了,无法为此做一个JSFIDLE,而且代码相当不言自明

 //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 predecessor = (typeof ($(this).attr('pre')) !== "undefined") ? $("#"+($(this).attr('pre'))) : null;
    drawlink(predecessor, $(this), $(this).attr('link'));
});
}

当然,它只是找到所有具有前置元素的元素(根据您的代码判断,这些元素具有
pre
属性)并向元素添加一个链接,该链接由它们的
link
属性指示

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'));
    }
  });
}
比如:

 $('[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 );
         }
    });

看起来,具有“link”类的元素可以有一个“pre”属性,该属性指定它们作为其前置元素的元素。假设每个元素只有一个前置元素。每个链接元素也有一个链接属性

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'));
    }
  });
}
drawlink函数有三个参数:前置变量、元素及其链接属性值

获取具有类链接的元素列表,然后对其进行迭代,并为每个具有非空pre属性的元素调用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'));
    }
  });
}
考虑到您要求的“高效”,上面的内容很简洁,但可能很慢,一个简单的脚本方法是:

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'));
    }
  }
}
函数(){
//使用普通JS和DOM
var links=document.querySelectorAll('.link');
var-el,pre;

对于(var i=0,iLen=links.length;i如何使用jquery通过其id获取前置元素?我可以做一个console.log(ttask[i]),但它会显示很多内容。首先,您不应该循环查找元素id。id应该是唯一的,您可以使用document.getElementById()找到元素我明白,我可能应该使用自定义属性task_id或其他东西。所有任务都有pre属性,但第一个任务不能有前置任务。getting error el.attr不是一个函数。当你说第一个任务不能有pre属性,但它有pre属性时,pre属性是空的吗?另外,很抱歉,忘记结束el如果$,code modifiedIts not empty,它包含0.hmm不做任何事情,没有错误,但没有链接箭头。对不起,字符串中有一个额外的空格,请立即尝试这几乎可以工作,但它不正确,因为if(i!=0){包装所有内容意味着任务一完全被遗漏。任务一可以是另一个任务,但它不能有任何自己的任务。@RobG,行得通!不确定我是否完全理解所有内容?你能用注释给出正确答案吗?我稍后会尝试,高效是我想要的!这实际上对我不起作用,因为元素传递给drawlink的“”不包含元素的宽度或高度属性。我得到了此错误项。宽度(…)为空。它将jQuery对象传递给drawlink,这是OP所做的,因此我不知道为什么会出现此错误。