在for循环中从jQuery编写CSS

时间:2013-01-27 23:17:28

标签: jquery

我的脚本需要在页面部分动态创建样式表(而不是在每个元素上放置内联样式,因为我需要稍后使用媒体查询覆盖这些样式)。

守则

for (var i=0; i<theElements.length; i++){

    $(theElements[i]).not('.responsive-wrap').each(function(i, elem){
        var theWidth = $(this).width();
        var parentWidth = $(this).parent().width();

        $(this).addClass('element' + [i]);

        $("#dynamicStylesheet").text('.element' + [i] + ' {max-width: ' + theWidth + 'px;}');
    });
}

主要问题是:

这完全覆盖了每个循环运行#dynamicStylesheet中的文本(所以当我加载页面时,.element22只有一个规则)。如何在不覆盖的情况下添加文本?​​

奖励分的子问题:

  • 这适用于大部分内容,但仅限于[i]为正方形时 括号。这是为什么?

    我在这里需要for loop,还是.each(function(){})本质上 无论如何创建for loop? <{1}}内的each以下的另一个for loop函数我还没有发布以保持简洁。

3 个答案:

答案 0 :(得分:2)

我不会在每次迭代期间添加文本。而是构建一个字符串,然后将其添加到元素中。这也提高了性能。

您不需要for循环。

var cssString = '';
$(theElements).not('.responsive-wrap').each(function(i, elem){
    var theWidth = $(this).width();
    var parentWidth = $(this).parent().width();

    $(this).addClass('element' + [i]);

    cssString += '.element' + [i] + ' {max-width: ' + theWidth + 'px;}';
});

$("#dynamicStylesheet").text(cssString);

答案 1 :(得分:1)

这是添加文本的快速方法,而不是每次都覆盖它

$("#dynamicStylesheet").text(
             $("#dynamicStylesheet").text()
             + '.element' + [i] + ' {max-width: ' + theWidth + 'px;}');

至于for循环,是each应该是你需要的全部。如果需要数字,可以添加一个计数变量。我还将$("#dynamicStylesheet")设置为循环外的变量,因此jQuery不必每次都查找元素 - 这是为了提高性能。

var i = 0,
    stylesheet = $("#dynamicStylesheet");

$(theElements).not('.responsive-wrap').each(function(){
    var theWidth = $(this).width();
    var parentWidth = $(this).parent().width();
    var elemName = "element" + i;

    $(this).addClass(elemName);

    stylesheet.text(
             stylesheet.text()
             + '.' + elemName + ' {max-width: ' + theWidth + 'px;}');
});

修改

如果theElements是一个标记名称数组,那么这样的内容会比我原来的更好。

var i = 0,
    stylesheet = $("#dynamicStylesheet");

$.each(theElements, function(){
  if( !$(this).hasClass('responsive-wrap') ){

    var theWidth = $(this).width();
    var parentWidth = $(this).parent().width();
    var elemName = "element" + i;

    $(this).addClass(elemName);

    stylesheet.text(
             stylesheet.text()
             + '.' + elemName + ' {max-width: ' + theWidth + 'px;}');
 }
});

未经测试,但应该有效..

答案 2 :(得分:1)

好的,那么,一些事情。假设theElements是HTML元素的数组,则each是不必要的。但情况似乎并非如此,因为您说element22正在显示(如果element0是一个数组,那么您编写的代码只会一次又一次地创建theElements HTML元素)。显然theElements是一个数组数组,或者是一个jQuery对象数组。鉴于它的名字,这是奇怪的,但让我们通过。

正如其他人所提到的,你每次迭代都会覆盖文本,这很糟糕。构建一个字符串稍微好一些,但是你仍然在做重复的字符串连接,这很慢。如果我们必须这样做,我们应该追加一个数组然后在最后将它们连接在一起(这更快,因为追加到字符串每次都会从头开始创建整个字符串。)

var css = [];
for (var i = 0; i < theElements.length; i++) {
    $(theElements[i]).not('.responsive-wrap').each(function(i) {
        var theWidth = $(this).width();
        $(this).addClass('element' + i);
        css.push('.element' + i + ' {max-width: ' + theWidth + 'px;}');
    });
}
$("#dynamicStylesheet").text(css.join('\n'));

现在,这有效,并且会做你想要的。但这几乎绝对不是你做任何事情的正确方法。在客户端上动态构建CSS并不好,除非你正在编写类似CSS编辑器的东西。有更简单的方法来解决导致你走这条道路的任何问题。

如果创建客户端样式表绝对重要,那么还有更好的方法可以做到这一点。创建一个适用于theElements元素的所有元素的CSS规则(哇,看看那个句子)。如果它们是随机选择的,那是不可能的,但是如果你通过一些逻辑查询到达它们,你可以在CSS中使用相同的那个。

[i]事情而言 - 我不知道该告诉你什么。由于JavaScript将数组串联化的奇怪方式,它们是等价的,如果i不适合你,那么就会出现问题。如果我是你,我将使用i.toString(),但i应该可以正常工作。

修改

如果theElements是一个标记名称数组,可以简化为:

var tagNames = theElements; // clear variable names are important!
var css = [];
$(tagNames.join(',')).not('.responsive-wrap').each(function(i) {
    var $this = $(this);
    $this.addClass('element' + i.toString());
    css.push('.element' + i.toString() + '{ max-width: ' + $this.width() + 'px; }');
});
$("#dynamicStylesheet").text(css.join('\n'));