Ответ 1
[..], Prototype не позволит элементу переключаться на видимый, если он был объявлен невидимым (
display: none
) с не-встроенным CSS. Это то, что я не понял и постоянно раздражаю. Любой, кто может дать какое-либо представление об этом, получает от меня большой запас.
Вы, вероятно, уже видели это, но документацию, например. show
(есть другие связанные функции с той же нотой), что:
Element.show
не может отображать элементы, скрытые с помощью стилей CSS. Обратите внимание, что это не ограничение Prototype, а следствие того, как работает CSSdisplay
.
Итак, это известная проблема, и они обвиняют CSS. Однако рассмотрим следующий документ (раньше я не использовал Prototype, поэтому я не уверен, что это рекомендуемый способ дождаться загрузки DOM, но, похоже, он работает):
<!doctype html>
<script src="prototype.js"></script>
<script>
document.observe("dom:loaded", function() {
$("victim").show();
});
</script>
<style>
p#victim {display:none;}
</style>
<p id="victim">Hello world!
Как вы уже знаете, это не сработает. Зачем? Ну, как Prototype знает, что для свойства < reset "display
, когда вы сообщаете p#victim
к show
самому себе? (Другими словами: как узнать, что должно было быть значением display
, если display: none
не было в наборе правил с помощью селектора p#victim
.) Ответ прост: он не может. (Подумайте об этом на секунду. Что, если другой набор правил изменит значение display
, если display: none
не присутствовал в нашем наборе правил с помощью селектора p#victim
? (Т.е. мы не можем предположить, что, например, p
всегда должно быть установлено на block
, другие правила могут изменить это значение.) Мы не можем удалить свойство display
из набора правил в таблице стилей, и мы не можем удалить все соединение между элементом и набор правил, потому что он может содержать другие свойства и т.д. (даже если было бы возможно, что это было бы imho, неочевидным, чтобы найти, какой набор правил для этого делать). Конечно, мы могли бы продолжать и продолжать с этим, но afaik нет известного решения этой проблемы.)
Тогда почему работает встроенная альтернатива? Во-первых, давайте посмотрим, как реализовано show
:
show: function(element) {
element = $(element);
element.style.display = ''; // <-- the important line
return element;
}
Вспомним единственную важную вещь, которую выполняет эта функция, - установить element.style.display
в пустую строку (''
), которая "удаляет" display
из style
. Большой! Но что это значит? Почему мы хотим удалить его?! Сначала мы должны выяснить, что element.style
действительно представляет и изменяет, когда мы изменяем его значения.
Документация MDC для element.style
гласит, что:
Возвращает объект, который представляет атрибут
style
.
Обратите внимание на последнее слово: атрибут. element.style
≠ текущий "вычисленный" стиль для элемента, это просто список свойств в атрибуте style
(см. MDC для более длинного/лучшего объяснения).
Рассмотрим следующий документ:
<!doctype html>
<script src="prototype.js"></script>
<script>
document.observe("dom:loaded", function() {
$("victim").show();
});
</script>
<p id="victim" style="display:none;">Hello world!
style="display:none;"
скрывает p#victim
, но когда DOM закончит загрузку Prototype, он изменит его на style=""
, и браузер пересчитает значение для свойства display
(значение из таблицы стилей по умолчанию браузера в этом случае).
Но рассмотрим следующий документ:
<!doctype html>
<script src="jquery.js"></script>
<script>
$(document).ready(function(){
$("#victim").show();
});
</script>
<style>
p#victim {display:none;}
</style>
<p id="victim">Hello world!
jQuery правильно обрабатывает файлы стилей, в любом случае! Это не так просто объяснить, как решение Prototype, и для меня есть много уровней awesomeness для чтения, и есть много случаев, когда jQuery не может вычислить правильное значение для display
. (Быстрая последняя заметка: Firebug..., но я предполагаю, что она использует некоторые эксклюзивные материалы Firefox или что-то в этом роде.)