Javascript CSS 不适用于 IE 7 中动态创建的元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2921845/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:30:03  来源:igfitidea点击:

CSS doesn't apply to dynamically created elements in IE 7?

javascripthtmlcssinternet-explorer-7internet-explorer-6

提问by Austin Hyde

Still looking for an answer.

还在寻找答案。

Changing or reassigning to the filter's innerHTMLsuccessfully redraws the element, but breaks my script, so that's out.

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

Adding additional child nodes, including text nodes, does not force a redraw. Removing the added node does not force a redraw.

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

Using the ie7.js family of scripts does not work.

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



In the project I am working on, I dynamically generate (with javascript) filters that look like this:

在我正在处理的项目中,我动态生成(使用 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>

And I have CSS that applies to each filter (for example):

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

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

However, it seems in IE 7 (and probably 6 for that matter), these styles don't get applied to the new filters.

然而,似乎在 IE 7(可能是 6)中,这些样式不会应用于新的过滤器。

Everything works perfectly in Firefox/Chrome/IE8.

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

Using the IE8 developer tools, set to IE7 mode, the browser can see the new elements, and can see the CSS, but just isn't applying the CSS.

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

Is there a way to force IE to reload styles, or perhaps is there a better way to fix this?

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



The JavaScript:(simplified)

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;
    }
}

回答by Austin Hyde

The problem, I've discovered is that IE 6/7 doesn't register the class name changes with elm.setAttribute('class','x')until the UI is redrawn.

我发现的问题是 IE 6/7 不会注册类名更改,elm.setAttribute('class','x')直到 UI 被重绘。

The solution is to use the form elm.className = 'x'

解决方法是使用表格 elm.className = 'x'

**This problem was also noticeable from moving from IE9 quirks to standards mode. The solution was the same.

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

回答by Josh Stodola

Sounds to me like you need to force a redraw of the UI for this element. There are several ways to do this, but the following is the most effective method...

在我看来,您需要为此元素强制重绘 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;

Here is another method I found on Ajaxian...

这是我在 Ajaxian 上找到的另一种方法......

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

回答by BalusC

IE6/7 has a lot of problems/bugs/misbehaviourswith regard to creating and adding elements in the DOM using createElement. I strongly recommend to switch to jQueryfor this since it does all the work in a cross browser compatible manner and has already taken (almost) all the IE6/7 specific misbehaviours into account so that you don't need to end up with a doubled amount of code to get it to work in all browsers the world is aware of. Here's a copy'n'paste'n'runnable SSCCE:

IE6 / 7有很多的问题/臭虫/ misbehaviours关于创建和使用DOM中的添加元素createElement。我强烈建议为此切换到jQuery,因为它以跨浏览器兼容的方式完成所有工作,并且已经(几乎)考虑到了所有 IE6/7 特定的不当行为,因此您不需要以翻倍的方式结束使其在世界所知的所有浏览器中工作的代码量。这是一个 copy'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>

Update: as per the comments, jQuery is absolutely not an option. Well, best what you can try is to set element attributes only afterthe element is been added to the DOM. Also try not to clone nodes in IE6/7, this is often epic fail. Rather create a brand new node from beginning on.

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

回答by Scott D. Strader

Building off of other comments and answers in this thread, I resolved this problem using the Prototype library:

基于此线程中的其他评论和答案,我使用 Prototype 库解决了这个问题:

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

Simply, get the parent and re-show it. Tested in IE8, using both Browser Mode: IE8, Document Mode: IE8 and Browser Mode: IE7, Document Mode: IE7. Have not tested with the dreaded quirks mode.

简单地,获取父项并重新显示它。在 IE8 中测试,使用浏览器模式:IE8、文档模式:IE8 和浏览器模式:IE7、文档模式:IE7。尚未使用可怕的怪癖模式进行测试。

回答by Tom

Don't you need a width as well as a height on the element? I know display: block should give it width: 100%, but IE is not that bright. Does anything change if you provide a width?

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

回答by fredrik

Could it be that you're missing " at the end of some elements?

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

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

回答by Sam

You have a missing "on the line that reads <a ... class="filter_delete_link>Delete</a>

"在读的那一行有一个缺失<a ... class="filter_delete_link>Delete</a>

Edit:
I don't think it's a problem with IE7 as it seems to work fine here - http://jsfiddle.net/nhvrA/.
I'll keep investigating.

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