jQuery for循环:eq / get - 压缩面包屑

时间:2012-11-05 08:50:56

标签: javascript jquery for-loop

我在压缩面包屑时遇到问题。如果面包屑到达许多元素,并跨越多行,我希望一些起始元素被压缩(“...”)。

ex 1

var height = $('#breadcrumbsContainer > span').height();
var length = $('#breadcrumbsContainer > span span').length;

while (height > 17) {

 for (var j = 1; j < length; j++) {
    if ($('#breadcrumbsContainer > span').get(j).find('a').text() != "...") {
        if ($('#breadcrumbsContainer > span').get(j).find('a').text("..."));
    }
    j++;
 }
};

ex 2

var height = $('#breadcrumbsContainer > span').height();
var length = $('#breadcrumbsContainer > span span').length;

while (height > 17) {

for (var j = 1; j < length; j++) {
    if ($('#breadcrumbsContainer > span:eq(j) a').text() != "...") {
        if ($('#breadcrumbsContainer > span:eq(j) a').text("..."));
    }
    j++;
}

};

在for循环中不使用“.get(j)”或:eq(j),所有内容都有效。每次我运行代码时,它似乎需要第一个元素,而不是第二个元素(j = 1 )。 (我不想压缩根节点)

jsFiddle示例:http://jsfiddle.net/TPqfK/3/

1 个答案:

答案 0 :(得分:1)

替代解决方案:我的原始答案仍在下面,但我正在考虑如何以不同的方式执行此操作,因此创建了以下代码的demo,其中更改{{1对于更大或更小的值将允许更多或更少省略号并将BREADCRUMBS_MAX_WIDTH更改为.last()将使更高级别的面包屑省略号化首先: - )

JavaScript(需要jQuery)

.first()

CSS

var BREADCRUMBS_MAX_WIDTH = 700;

function crumbsWidth() {
  var width = 0;
  $('#breadcrumbs li').each(function() {
    width += $(this).outerWidth();
  });
  return width;
}

while (crumbsWidth() >= BREADCRUMBS_MAX_WIDTH && $('#breadcrumbs li').length - 2 !== $('#breadcrumbs li.ellipsis').length) {
  $('#breadcrumbs li:not(:first-child):not(:last-child):not(.ellipsis)').last().addClass('ellipsis');
}

HTML

#breadcrumbs {
  margin:0;
  padding:0;
  list-style-type:none;
  font-size:0;
}
#breadcrumbs li {
  display:inline-block;
  font-size:16px;
  padding-left:4px;
}
#breadcrumbs li:not(:first-child):before {
  content:'\002192  ';
}
.ellipsis {
  width:60px;
  overflow:hidden;
  white-space:nowrap;
  text-overflow:ellipsis;
}

原始回答:

最初我在添加小提琴之前运行代码时遇到了一些问题,我将首先介绍。

<ul id="breadcrumbs"> <li>Lorem ipsum dolor</li> <li>sit amet, consectetur</li> <li>adipisicing elit, sed</li> <li>do eiusmod tempor</li> <li>incididunt ut labore</li> <li>et dolore magna aliqua</li> <li>Ut enim ad minim</li> </ul> 控制流语句可能导致无限循环,这可能导致100%CPU并可能导致浏览器或选项卡崩溃。我在小提琴中看到你提供了一种突破循环的方法,但问题中的代码应该完全描述问题。

while (height > 17)存在选择器问题,因为您使用的是CSS子组合$('#breadcrumbsContainer > span'),它只返回直接子项,而不是所有后代。在你的小提琴中加上这个标记:

>

选择器正在查找 <div id="breadcrumbsContainer"> <span id="ctl00_breadcrumb"> <span><a style="text-decoration: none;" href="#">Min startside</a></span> <span></span> <span><a style="text-decoration: none;" href="#">dfa as dfdsa dsa fdsfas</a></span> <span></span> <span><a style="text-decoration: none;" href="#">a fdsa fsd adsfdsasad fdsa</a></span> <span></span> <span><a style="text-decoration: none;" href="#">test aff for log og opr sds</a></span> <span></span> <span><a style="text-decoration: none;" href="#">TESTs sds</a></span> <span></span> <span>anders er awesome</span> </span> </div>​ 而不是面包屑跨度。因此,您可能需要将其更正为<span id="ctl00_breadcrumb">

这仍然无法解决问题,因为使用$('#breadcrumbsContainer span span')将导致JavaScript错误,因为.get()返回DOM元素而不是jQuery包装对象,因此您无法在其上调用$('#breadcrumbsContainer span span').get(j)

使用:eq()的第二个示例也不起作用,因为.find()变量是选择器字符串的一部分,而不是变量值,并且不会在jQuery中导致错误。所以,

j

应该是

$('#breadcrumbsContainer > span:eq(j) a')

但是,通过所有这些更改,由于$('#breadcrumbsContainer > span:eq(' + j + ') a') 的操作方式,结果选择器仍然无效。从文档

  

:eq过滤与之前的表达式匹配的元素集

所以:eq()将选择所有面包屑和间隔元素,然后应用过滤器。因此$('#breadcrumbsContainer span span')将成为第一个面包屑,:eq(0)将成为第一个 spacer span

因此,考虑到所有这些变化,我们最终得到:

:eq(1)

注意:以上循环可行,但由于以下原因效率不高:

  1. 可以删除用于填充面包屑的空for (var j = 2; j < length; j++) { // <--- starts at 2 (do not change first breadcrumb) if ($('#breadcrumbsContainer span span:eq(' + j + ') a').text() != "...") { if ($('#breadcrumbsContainer span span:eq(' + j + ') a').text("...")); } j++; } 元素,以支持使用CSS间隔每个面包屑
  2. 使用更多语义标记来描述数据,例如<span>而不是
  3. <ul><li></li></ul>选择器是jQuery扩展,不是CSS规范的一部分,查询使用:eq()无法利用本机DOM提供的性能提升querySelectorAll()方法 {{3 }}
  4. 可能更容易使用[docs] CSS属性:eq()并更改每个痕迹的宽度,而不是更改text-overflow:ellipsis文字。