CSS не применяется к динамически созданным элементам в IE 7?
Ищем ответ.
Изменение или переназначение фильтра innerHTML
успешно перерисовывает элемент, но прерывает мой script, поэтому out.
Добавление дополнительных дочерних узлов, включая текстовые узлы, не вызывает перерисовки. Удаление добавленного node не приводит к перерисовке.
Использование семейства скриптов 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;
}
}
Ответы
Ответ 1
Проблема, я обнаружил, что IE 6/7 не регистрирует изменения имени класса с помощью elm.setAttribute('class','x')
, пока пользовательский интерфейс не будет перерисован.
Решение состоит в использовании формы elm.className = 'x'
** Эта проблема также была заметна при переходе от режима IE9 к стандартным режимам. Решение было таким же.
Ответ 2
Звучит так, как будто вам нужно принудительно перерисовать пользовательский интерфейс для этого элемента. Существует несколько способов сделать это, но наиболее эффективным является метод...
// 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;
}
Ответ 3
В IE6/7 есть много проблем/ошибок/неправильных настроек в отношении создания и добавления элементов в 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>
Обновить: в соответствии с комментариями jQuery абсолютно не вариант. Наилучшим образом, лучше всего попробовать установить атрибуты элементов только после добавления элемента в DOM. Также старайтесь не клонировать узлы в IE6/7, это часто эпический провал. Скорее создайте новый node с самого начала.
Ответ 4
Может быть, вам не хватает "в конце некоторых элементов?"
<a ... class="filter_delete_link>Delete</a> missing "
<div class="filter_field> missing "
Ответ 5
У вас отсутствует "
на строке, которая читает <a ... class="filter_delete_link>Delete</a>
Edit:
Я не думаю, что это проблема с IE7, поскольку, похоже, здесь все отлично работает - http://jsfiddle.net/nhvrA/.
Я продолжу расследование.
Ответ 6
Вам не нужна ширина и высота элемента? Я знаю, дисплей: блок должен дать ему ширину: 100%, но IE не такой яркий. Что-то меняется, если вы предоставляете ширину?
Ответ 7
Построение других комментариев и ответов в этом потоке, я решил эту проблему, используя библиотеку Prototype:
<div id"dynamically-added-block"> ... </div>
...
$("dynamically-added-block").up().show();
Просто выберите родителя и повторите его. Протестировано в IE8, используя оба режима браузера: IE8, режим документа: IE8 и режим браузера: IE7, режим документа: IE7. Не тестировались в режиме ужасных причуд.