1

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

编码

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 loopeach在这个函数下面还有另一个函数for loop,我没有发布它以保持简洁。

4

3 回答 3

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);
于 2013-01-27T23:25:38.833 回答
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;}');
 }
});

未经测试,但应该可以工作..

于 2013-01-27T23:20:06.877 回答
1

好的,所以,有几件事。假设这theElements是一个 HTML 元素数组,则each是不必要的。但情况似乎并非如此,因为您说正在显示(如果是 HTML 元素数组,element22您编写的代码只会element0一遍又一遍地创建)。theElements所以显然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 编辑器的东西。有很多更简单的方法可以解决导致您走上这条道路的任何问题。

如果创建客户端样式表绝对重要,那么也有更好的方法来做到这一点。创建一个适用于所有元素的 CSS 规则theElements(哇,看看那句话)。如果它们是随机选择的,这是不可能的,但如果你通过一些逻辑查询找到它们,你可以在 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'));
于 2013-01-27T23:38:51.287 回答