如何替换CSS /切换大量元素?

时间:2012-04-04 23:28:03

标签: jquery

编辑:这个问题演变成如何优化大规模的CSS更改为700或更多div。我将在下面留下旧问题来描述我原来的方法。

我有以下jQuery但它的行为并不像我期望的那样。有大约700个div与类gr,所以隐藏它们需要一个明显的时间。我想做的是:

  1. 单击“显示/隐藏发音”时,立即将该文本更改为“正在工作”
  2. 等到隐藏/显示所有'div.gr'
  3. “工作”可以追溯到“显示/隐藏发音”

    $(document).ready(function () {
     $('#togglePron').click(function() {
       $('#togglePron').html("Working...");
       $('div.gr').toggle();
       $('#togglePron').html("Show/hide Pronunciation");
      });
    });
    ...
    ... 
    <div class="pronlink" id="togglePron">Show/hide P</div>
    
    <div class="gr">hai</div><div class="zi">A</div>
    <div class="gr">nao</div><div class="zi">B</div>  
    etc.
    
  4. 感谢Mike Lentini there's a jsfiddle for this question.

    This is the full page I'm working on

    我观察到的行为是“显示/隐藏P”需要一段明显的时间来改变,然后它会短暂地改变为“工作”,然后它会回到“显示/隐藏”状态。那么jQuery将html()和.toggle()聚合在一起,而不是先运行html()吗?

    这似乎是浏览器特定的,因为在Opera中它做了我想要的。在IE 7和Chrome 18中,行为如我所述。有没有办法让Chrome中我想要的行为发生?或者更好的方式来做我正在描述的事情?

6 个答案:

答案 0 :(得分:6)

编辑:

为什么不在所有元素上交换类,而不是使用toggle函数来绑定事件?这应该更多更快:

$(document).ready(function(){
  $('#toggleP').click(function(){
    $('.gr').toggleClass('hidden');
  });
});

然后在CSS中添加以下样式:

.hidden { display: none !important; }

有关示例,请参阅this fiddle

其他编辑:

kingjeffrey所述,类交换父元素而不是子元素更有效:

JS:
$('#togglePron').click(function(){
  $('table').toggleClass('hide-pron');
});

CSS:
table.hide-pron .gr { display: none !important; }

对于(相对)少数儿童,这些方法之间的差异可以忽略不计 - 但随着儿童数量的增加,交换父类的速度会明显加快。


原始答案:

click()函数返回之前,您的元素不会更新。这是一种方式(可能不是最佳方式):

$(document).ready(function () {
  $('#toggleP').click(function() {
    $('#toggleP').html("Working...");
    setTimeout(
      "$('div.g').toggle(10,function(){$('#toggleP').html('Show/Hide P');});",
      10)
  });
});

toggle()现在是异步的,因为将来通过setTimeout()“预定”10ms。这意味着click()函数几乎可以立即返回,而无需等待toggle()完成。

正如其他人所说,最好的选择可能是将所有div包装在父级中(如果这对您的实际代码可行),然后切换父级div

JSFiddle链接:http://jsfiddle.net/5E45Q/

答案 1 :(得分:3)

如果您可以将所有div.g分组到父元素中,则可以隐藏该单个父元素而无需修改DOM 700次。见http://jsfiddle.net/SVf5k/6/

但如果这是不可避免的,您可以在切换div.g之前添加一个短暂的延迟。这将为js引擎提供更改#toggleP上的html的机会。见http://jsfiddle.net/SVf5k/5/

答案 2 :(得分:2)

编辑:我原来的答案旨在解决您为什么只在短暂的时间内看到“工作......”并且直到toggle()才看到效果的混淆一段时间在实际查看您正在构建的网站时,我可以看到您真正关心的是简单地将此UI更新更快,在这种情况下,我强烈推荐Justin's answer(尽管我也是有兴趣解释为什么会出现如此巨大的性能差异。)


简短的回答:我认为你想要的是一个异步迭代器,我已经看过其他项目的手工滚动,但奇怪的是我不认为我在开源库中看到过(并不意味着它不存在 - 我只是没有看到它。)

Something like this.

你可以看到here它的行为方式(我认为)是你期望的。

现在,为了解释:

  

jQuery将html()和.toggle()聚合在一起,而不是先运行html()?

我不认为这是jQuery;我相信这是与浏览器相关的行为,关于浏览器的呈现引擎如何处理来自事件循环的UI更新。我知道很多UI实现不是即时更新UI元素,而是仅在处理的每个事件之间。

对于浏览器我的一般观察(我不是真正的权威;你必须与实际的浏览器贡献者交谈)是一些 UI更新立即发生,并且某些除了通过事件循环的每次完整传递外没有可见效果。所以在我看来,无论jQuery在toggle()的引擎盖下做什么都属于后者。

答案 3 :(得分:1)

一种方法是使用javascript直接动态修改css样式(不是每个元素)。

在您的网页中,每个<td>中的所有文字div都有class='gr'个内联style="display:block;"。首先,我将display:block;移动到样式表中(最好是第一个位置)。

使用此SO answer(和this page,以及此SO answer),我会浏览每个样式表,直到您获得您感兴趣的样式表(添加标题为<css />将允许您轻松完成此操作)。删除显示块(这是一个简单的stylesheet.deleteRule(<index>)索引将为零,因为你把它放在.css中)。添加新的display:none;

这将基本上改变页面的整个css,而不是单独更改PER元素,因为你不得不使用JQuery。

也许不是最受欢迎的解决方案,但仍然允许您保留当前的设计(不重复信息)并使用css来实现它的假设(“动态”)。


跟进: 很好找"Totally Pwn CSS with Javascript"。确切地说,我会在你的情况下做什么(想在这里为后人添加:))

另外,有人应该向JQuery提出功能请求,以便能够轻松地执行此类操作。 :)


跟进2: 刚才意识到其他人在我之前发布了解决方案

另一种方法是删除'gr'类并添加另一个'grHide'类。 看看这个fiddle,看看我的意思。

如上所述,将内联display:block;移动到.gr类下的css样式表中。添加一个单独的类,它可以执行所有操作.gr确实可以执行display:none;

这应该允许你使用jquery并且仍然非常快。无论如何,小提琴很快。

答案 4 :(得分:0)

如果查看jQuery文档,您会看到toggle()有回调 - 但如果您想要回调,还必须指定持续时间。因此,您的代码可能类似于:

$(document).ready(function () {
  $('#toggleP').click(function() {
    $('#toggleP').html("Working...");
    $('div.g').toggle(500, function() {
      $('#toggleP').html("Show/hide P");
    });
  });
});
...
... 
<div class="plink" id="toggleP">Show/hide P</div>

如果半秒钟对你来说是一个很好的持续时间。点击此处:http://api.jquery.com/toggle/

编辑:快速jsfiddle:http://jsfiddle.net/SVf5k/

答案 5 :(得分:0)

在这里使用$.ajax()小提琴:http://jsfiddle.net/SVf5k/10/

$(function () {
    $('#toggleP').click(function() {
       $(this).html("...Working...");

        $.ajax({
           success: function(){
              $('div.g').toggle(500, function() {
                     $('#toggleP').html("Show/hide P");
              });
          }
      })
  });
});
​
相关问题