CSS не применяется к динамически создаваемым элементам в IE 7? - PullRequest
14 голосов
/ 27 мая 2010

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

Изменение или переназначение фильтра 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;
    }
}

Ответы [ 7 ]

24 голосов
/ 02 июня 2010

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

Решение - использовать форму elm.className = 'x'

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

5 голосов
/ 27 мая 2010

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

// 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;
}
1 голос
/ 27 мая 2010

IE6 / 7 имеет множество проблем / ошибок / неправильных действий в отношении создания и добавления элементов в DOM с использованием createElement. Я настоятельно рекомендую для этого переключиться на 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>

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

0 голосов
/ 10 июня 2010

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

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

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

0 голосов
/ 27 мая 2010

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

0 голосов
/ 27 мая 2010

В строке отсутствует ", которая гласит <a ... class="filter_delete_link>Delete</a>

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

0 голосов
/ 27 мая 2010

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

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