【问题标题】:loop through if, return if false, if true => stop if循环 if,如果为假则返回,如果为真 => 则停止
【发布时间】:2012-03-04 01:29:21
【问题描述】:

所以我得到了以下场景:

$('.menu').find('a').each( function(el, val) {
  if( window.location.hash !== val.hash ) {
    $('.menu li').first().addClass('active') // we found no valid hash for us, so set first <li> active
    $('#hash1').show() // and show the first content
  } else {
    $(this).parent().addClass('active') // we found an hash, so give its parent <li> an active class
    $(window.location.hash).show() // can be #hash2, #hash3, whatever
    return false; // since we found something, stop the if.
  }
});

现在很明显,每次我们发现没有有效的散列时,我们将第一个元素设置为活动并显示第一个内容......但我不希望那样。

我希望 if 在我们进入 else 语句之前首先遍历所有元素。然后如果我们什么也没找到,则将第一个元素设置为活动并显示第一个内容。

因为我循环遍历每个“a”,我该怎么做?

【问题讨论】:

    标签: javascript jquery loops if-statement


    【解决方案1】:

    只需在循环之外保留一个变量:

    var found = false;
    
    $('.menu').find('a').each( function(el, val) {
        if( window.location.hash === val.hash ) {
            $(this).parent().addClass('active'); // we found an hash, so give its parent <li> an active class
            $(window.location.hash).show(); // can be #hash2, #hash3, whatever
    
            found = true;
        }
    });
    
    
    if(!found) {
        $('.menu li').first().addClass('active'); // we found no valid hash for us, so set first <li> active
        $('#hash1').show(); // and show the first content
    }
    

    另外,语句末尾的分号不是可选的。

    【讨论】:

    • “另外,语句末尾的分号不是可选的。” 是的。 (在 JavaScript 中一般情况下不是 100%,但在这段代码中的语句中肯定是 100%。)
    • @nnnnnn:我再说一遍,不是可选的。是的,口译员会为您添加它们。是的,这是“合法的”。这也导致了糟糕的代码。不是可选的;)
    • blog.izs.me/post/2353458699 “JavaScript 社区的思想领袖继续传播不确定性而不是理解,这是公然不负责任的行为。”
    • 在你的 `if' 中看起来像一个未定义的this 比分号更重要
    • 这仍然循环遍历元素并显示 #hash1 的内容,这正是 OP 不想要的。
    【解决方案2】:

    您可以使用.filter() 来获取您想要的元素。如果没有选择,则执行默认操作:

    var $links = $('.menu').find('a').filter(function() {
        return window.location.hash === this.hash;
    });
    
    if($links.length > 0) {
        $links.parent().addClass('active');
        $(window.location.hash).show();
    }
    else {
        $('.menu li').first().addClass('active');
        $('#hash1').show();
    }
    

    参考.filter

    【讨论】:

    • 可能不是,我确定filter 在内部使用each。我只是觉得它更干净一些,因为它避免了额外的标志。
    • 刚刚在 jsperf 上测试过。它们之间几乎没有区别。谢谢!
    【解决方案3】:

    如果你能用英语更清楚地解释你的要求,我想你会发现 JavaScript 结构自然会遵循。

    以下是我对您尝试执行的操作的最佳猜测:“.menu”中具有与 .hash 相同的 window.location.hash 的所有锚点都应该将其父 li 设为“活动”,并且相应的显示的元素。如果没有匹配项,则应将第一个菜单项设为“活动”并显示“#hash1”。

    var matched = false;
    $('.menu').find('a').each( function(el, val) {
      if( window.location.hash === val.hash ) {
        matched = true;
        $(this).parent().addClass('active');
        $(window.location.hash).show();
      }
    });
    if (!matched) {
        $('.menu li').first().addClass('active');
        $('#hash1').show();
    }
    

    【讨论】:

      【解决方案4】:
      var elm = $(window.location.hash).length ? window.location.hash : '#hash1';
      $(elm).show();
      $('a[href$="'+elm+'"]').parent().addClass('active');
      

      假设#hash1 的标记与其他标记相同,并且浏览器地址栏中只有一个哈希(或没有)?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-01
        • 1970-01-01
        • 2017-07-28
        • 2019-03-10
        • 2023-03-22
        • 2012-05-13
        • 1970-01-01
        • 2021-10-15
        相关资源
        最近更新 更多