CSS не применяется к динамически созданным элементам в IE 7?

все еще ищу ответ.

изменение или переназначение фильтра innerHTML успешно перерисовывает элемент, но ломает мой скрипт, так что это не так.

добавление дополнительных дочерних узлов, включая текстовые узлы,не вызывает перерисовки. Удаление добавленного узла не вызывает перерисовки.

используя ИЕ7.семейство сценариев 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;
    }
}

7 ответов


проблема, я обнаружил, что IE 6/7 не регистрирует изменения имени класса с elm.setAttribute('class','x') пока интерфейс перерисовывается.

решение заключается в использовании форма elm.className = 'x'

**эта проблема также была заметна при переходе от причуд IE9 к режиму стандартов. Решение было таким же.


мне кажется, нужно вызвать перерисовку интерфейса для данного элемента. Существует несколько способов сделать это, но наиболее эффективным является следующий метод...

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

вот еще один способ я нашел на Ajaxian...

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

IE6 / 7 имеет много проблемы/ошибки/проступки что касается создания и добавления элементов в DOM с помощью createElement. Настоятельно рекомендую переключиться на jQuery для этого, так как он делает всю работу в кросс-браузере совместимым образом и уже принял (почти) все конкретные проступки IE6/7 во внимание, так что вам не нужно в конечном итоге с удвоенным количеством кода, чтобы заставить его работать во всех браузерах, о которых знает мир. Вот копия'paste-эн-эн'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>

обновление: согласно комментариям, jQuery абсолютно не вариант. Ну, лучшее, что вы можете попробовать это установить атрибуты элемента только после элемент добавлен в DOM. Также старайтесь не клонировать узлы в IE6 / 7, это часто эпический сбой. Скорее создайте новый узел с самого начала.


может быть, вам не хватает " в конце некоторых элементов?

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

отсутствует " на строку <a ... class="filter_delete_link>Delete</a>

Edit:
Я не думаю, что это проблема с IE7, поскольку она, похоже, работает нормально здесь -http://jsfiddle.net/nhvrA/.
Я продолжу расследование.


не нужна ширина, а также высота элемента? Я знаю дисплей: блок должен дать ему ширину: 100%, но IE не настолько яркий. Что-нибудь изменится, если вы предоставите ширину?


построение других комментариев и ответов в этом потоке, я решил эту проблему, используя библиотеку прототипов:

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

просто, получить родителя и повторно показать его. Протестировано в IE8, используя оба режима браузера: IE8, режим документа: IE8 и режим браузера: IE7, режим документа: IE7. Не протестировали с ужасным режимом quirks.