【问题标题】:CSS doesn't apply to dynamically created elements in IE 7?CSS 不适用于 IE 7 中动态创建的元素?
【发布时间】:2011-02-24 16:43:37
【问题描述】:

仍在寻找答案。

更改或重新分配给过滤器的innerHTML 会成功重绘元素,但会破坏我的脚本,所以就这样了。

添加其他子节点(包括文本节点)不会强制重绘。删除添加的节点不会强制重绘。

使用 ie7.js 系列脚本不起作用。


在我正在进行的项目中,我动态生成(使用 javascript)过滤器,如下所示:

<div class="filter">
    <a ... class="filter_delete_link">Delete</a>
    <div class="filter_field">
        ...
    </div>
    <div class="filter_compare">
        ...
    </div>
    <div class="filter_constraint">
        ...
    </div>
    <div class="filter_logic">
        ...
    </div>
</div>

我有适用于每个过滤器的 CSS(例如):

.filter a.filter_delete_link{
    display:block;
    height:16px;
    background: url('../images/remove_16.gif') no-repeat;
    padding-left:20px;
}

但是,在 IE 7(也可能是 6)中,这些样式似乎不适用于新的过滤器。

一切都在 Firefox/Chrome/IE8 中完美运行。

使用IE8开发者工具,设置为IE7模式,浏览器可以看到新元素,也可以看到CSS,只是没有应用CSS。

有没有办法强制 IE 重新加载样式,或者有没有更好的方法来解决这个问题?


JavaScript:(简体)

var builder = {
    ...
    createNewFilter: function() {
        var newFilter = document.createElement('div');

        var deleteLink = document.createElement('a');
        deleteLink.href = '#';
        deleteLink.setAttribute('class','filter_delete_link');
        deleteLink.title = 'Delete Condition';
        deleteLink.innerHTML = "Delete";
        newFilter.appendChild(deleteLink);

        var field = document.createElement('div');
        field.setAttribute('class','filter_field');
        var fieldSelect = this.getFieldSelectBox();
        field.appendChild(fieldSelect);
        newFilter.appendChild(field);

        // more of the same...

        deleteLink.onclick = function() {
            builder.removeFilter(newFilter);
        };
        fieldSelect.onchange = function () {
            builder.updateFilter(newFilter);
        }

        return newFilter;
    },
    addNewFilter: function() {
        var nNewFilter = this.createNewFilter(this.numFilters++);
        this.root.insertBefore(nNewFilter,this.nAddLink);

        //other unrelated stuff...

        //provided by Josh Stodola
        //redraw(this.root);

        return nNewFilter;
    }
}

【问题讨论】:

  • 在您的真实页面中,您是否有多个“类”值?当容器和​​被容器在“类”中都有多个值时,IE 可能对“.foo .bar”规则非常愚蠢。
  • Pointy,我不使用多个类,正是因为这个原因:) 我什至尝试将 css 简化为 .filter_delete_link,但不行。
  • IE6 有多个类的问题,IE7 不应该。
  • 调整窗口大小时,样式最终是否应用于动态元素?
  • 调整窗口大小没有任何作用。

标签: javascript html css internet-explorer-7 internet-explorer-6


【解决方案1】:

问题是,我发现 IE 6/7 在重绘 UI 之前不会使用 elm.setAttribute('class','x') 注册类名更改。

解决办法是使用elm.className = 'x'的形式

**这个问题在从 IE9 怪癖转移到标准模式时也很明显。解决方法是一样的。

【讨论】:

    【解决方案2】:

    在此线程中的其他 cmets 和答案的基础上,我使用 Prototype 库解决了这个问题:

    <div id"dynamically-added-block"> ... </div>
    ...
    $("dynamically-added-block").up().show();
    

    只需获取父级并重新显示即可。在 IE8 中测试,同时使用浏览器模式:IE8、文档模式:IE8 和浏览器模式:IE7、文档模式:IE7。尚未使用可怕的怪癖模式进行测试。

    【讨论】:

    【解决方案3】:

    在我看来,您需要为此元素强制重绘 UI。有几种方法可以做到这一点,但以下是最有效的方法...

    // elm is a reference to your element
    var disp = elm.style.display;
    elm.style.display = "none";
    var redrawFix = elm.offsetHeight;
    elm.style.display = disp;
    

    这是另一种方法I found on Ajaxian...

    function redraw(elm) {
      var n = document.createTextNode(' ');
      elm.appendChild(n);
      setTimeout(function(){ n.parentNode.removeChild(n) }, 0);
      return elm;
    }
    

    【讨论】:

    • 好吧,第一种方法不起作用,第二种方法失败,因为IE不知道Function.prototype.defer是什么。
    • @Austin 哎呀,你是对的。 defer 是一个 Prototype(JS 框架)函数,它在解释器空闲之前保持函数调用。我已经更新了我的答案,不依赖于该框架函数,而是使用类似的方法。
    • 我明白你想要做什么。但是,它不起作用。我尝试更改超时以等待更长的时间,但没有奏效。我试着只留下额外的节点。没有结果。起作用的是elm.innerHTML += ' ';,但这搞砸了我的事件(不知道为什么),所以我需要摆脱这个空间。
    • 用 javascript 更新了我的问题。
    【解决方案4】:

    你不需要元素的宽度和高度吗?我知道 display: block 应该给它 width: 100%,但 IE 不是那么亮。如果提供宽度,有什么变化吗?

    【讨论】:

    • 我实际上确实给它一个宽度以另一种样式。
    【解决方案5】:

    IE6/7 有很多关于使用createElement 在 DOM 中创建和添加元素的problems/bugs/misbehaviours。我强烈建议为此切换到jQuery,因为它以跨浏览器兼容的方式完成所有工作,并且已经(几乎)考虑了所有 IE6/7 特定的错误行为,因此您不需要最终得到加倍的代码让它在全世界都知道的所有浏览器中工作。这是一个可复制的'n'paste'n'runnable SSCCE

    <!doctype html>
    <html lang="en">
        <head>
            <title>Test</title>
            <script src="http://code.jquery.com/jquery-latest.min.js"></script>
            <script>
                $(document).ready(function() {
                    $('#add').click(function() {
                        var newElement = $('<div class="filter"><a href="#" class="delete">delete</a></div>');
                        $('#container').append(newElement);
                    });
                });
            </script>
            <style>
                .filter { background: pink; }
                .delete { background: yellow; }
            </style>
        </head>
        <body>
            <div id="container"></div>
            <button id="add">add</button>
        </body>
    </html>
    

    更新:根据 cmets,jQuery 绝对不是一个选项。好吧,您可以尝试的最好的方法是仅在元素被添加到 DOM 之后 设置元素属性。也尽量不要在 IE6/7 中克隆节点,这通常是史诗般的失败。而是从头开始创建一个全新的节点。

    【讨论】:

    • 希望我可以切换到 jQuery,它是我通常使用的。但是,现在不是一个选择:(
    • 为什么不呢?无论如何,尝试在元素被添加到 DOM 之后 设置元素属性。也尽量不要在 IE6/7 中克隆节点,这通常是史诗般的失败。而是从头开始创建一个全新的节点。
    • 好吧,我之前添加了属性,然后克隆了,所以我会尝试修复它。
    • 好吧,只是想看看这是否是问题所在,我尝试了这个(添加和克隆之前的属性):jsfiddle.net/YMDrQ。在 IE 6/7 中,它可以完美运行。
    【解决方案6】:

    &lt;a ... class="filter_delete_link&gt;Delete&lt;/a&gt; 的行上缺少"

    编辑:
    我认为这不是 IE7 的问题,因为它似乎在这里工作正常 - http://jsfiddle.net/nhvrA/.
    我会继续调查。

    【讨论】:

    • 我没有使用 jQuery(我想成为,grumble,grumble)。也许 jQuery 有一些代码可以重新加载样式?
    【解决方案7】:

    可能是您在某些元素的末尾缺少 " 吗?

    <a ... class="filter_delete_link>Delete</a> missing "
    <div class="filter_field> missing "
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      相关资源
      最近更新 更多