Как устранить пост-рендер "мерцание"?
Я изо всех сил старался быть пуристом с использованием методов Javascript/Ajax, гарантируя, что все Ajax-y поведение является улучшением базовых функций, а сайт также полностью работоспособен, когда Javascript отключен. Однако это вызывает некоторые проблемы.
В некоторых случаях DOM node должен отображаться только в том случае, если в браузере включен Javascript. В других случаях он должен быть видимым только при отключении. Возьмем, например, кнопку отправки в форме, которая имеет выпадающий список с обработчиком onchange, который автоматически отправляет (используя плагин формы JQuery):
<form method="post" action=".">
<label for="id_state">State:</label>
<select name="state" id="id_state" onchange="$(this.form).ajaxSubmit(ajax_submit_handler);">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
</select>
<input class="with_js_disabled" type="submit" value="OK" />
</form>
и Javascript:
<script type="text/javascript">
$(document).ready(function()
{
$(".with_js_disabled").hide();
});
</script>
Когда Javascript включен, кнопка отправки не требуется (из-за обработчика onchange). Однако функция JQuery $(document).ready(и более прямая document.onload) вызывается только после того, как страница была полностью загружена и отображена - следовательно, сначала отображается кнопка отправки и появляется "вспышка", когда Javascript и на дисплее node установлено значение "none".
Я принял это как стоимость ведения бизнеса и не нашел пути вокруг него. Но есть ли техника, о которой я не знаю, что минимизирует эффект или даже полностью устранит ее?
EDIT:
Решение <noscript>
, упомянутое многими людьми ниже, кажется многообещающим, но не работает для меня в Safari. Однако предварительное предложение Престола прекрасно работает:
<body>
<script type="text/javascript">
document.body.className += ' has_js';
</script>
<!-- the rest of your page -->
</body>
В этом случае можно использовать стильный CSS:
body .js_enabled_only { display: none; }
body .js_disabled_only { display: block; }
body.has_js .js_enabled_only { display: block; }
body.has_js .js_disabled_only { display: none; }
Эта вторая строка предназначена только для справки и может (и должна) удаляться, чтобы избежать ситуаций, когда ваш элемент не должен отображаться: block. Аналогично, для других стилей отображения вам могут потребоваться разные варианты в третьей строке. Но это решение красиво и чисто, IMO, и в моих тестах полностью устраняет эффект мерцания.
Ответы
Ответ 1
Как объединить некоторые из этих решений:
<style type="text/javascript">
.only-without-script {
display: none;
}
</style>
<noscript>
<style type="text/javascript">
.only-with-script {
display: none;
}
.only-without-script {
display: block;
}
</style>
</noscript>
или я предпочитаю добавлять класс в тело (поместите тэг <script>
в верхнюю часть тела и не используйте событие .ready):
<head>
<style type="text/javascript">
body.has-script .something-not-ajaxy {
display: none;
}
input.ajaxy-submit {
display: none;
}
body.has-script input.ajaxy-submit {
display: inline;
}
</style>
</head>
<body>
<script type="text/javascript">
document.body.className += ' has-script';
</script>
<!-- the rest of your page -->
</body>
Ответ 2
В ситуациях, идентичных вашим, я обычно помещаю кнопку отправки вокруг тега <noscript>
. Никто не предложил это, поэтому я не уверен, что это считается плохой практикой вокруг этих частей, но это то, что я использую, и это работает для меня.
Если вы хотите, чтобы только node отображался, когда включен Javascript, вы можете сделать это в голове:
<noscript>
<style type="text/css">
.js-enabled { display: none; }
</style>
</noscript>
И затем дайте любым Javascript-элементам класс js-enabled
.
Ответ 3
Как и Дэвид сказал, вы можете добавить Javascript, который добавляет таблицу стилей, чтобы скрыть все "лишние" html-элементы:
<head>
...
<script type="text/javascript" language="javascript">
document.write('<style type="text/css"> .disabled-if-javascript { display: none; } </style>');
</script>
</head>
...
Если Javascript включен, он устанавливает все элементы класса "disabled-if-javascript" в спрятанное, прежде чем тело будет загружено. Просто добавьте этот класс ко всем элементам, которые должны быть скрыты, если включен javascript. Вам также может понадобиться класс enabled-if-javascript, который делает обратное, чтобы показать определенные элементы, которые будут скрыты для не-javascript. Возможно, вам нужно добавить "!important
" в ваше определение стиля там, чтобы переопределить существующие (не javascript) правила.
Ответ 4
Я могу представить два метода:
1 - Предварительно определите, включен ли Javascript и сохранит эту информацию в файле cookie/сеансе. Это можно сделать на первой странице и устранить большинство мерцаний.
2 - Используйте livequery plugin, который обнаруживает элементы, поскольку они добавлены в DOM. Вы можете запустить его сразу, когда Javascript заканчивает загрузку, что должно быть намного до документа (это его в голове).
$('.with_js_disabled').livequery(function() {
$(this).hide();
});
Ответ 5
Просто мысль: я не уверен, что это сработает, но вы можете попробовать добавить Javascript в голову документа, чтобы написать элемент стиля CSS, который скроет кнопку.
Ответ 6
Простая вещь: добавьте <script>jQuery.ready();</script>
прямо перед закрытием тега body.
Это заставит все привязки к событию "ready" для запуска. И если вы запустите их в конце документа, DOM будет загружен и готов к работе, даже если "родное" событие onDomContentLoaded еще не запущено.
Это обычно работает для меня, когда я хочу удалить мерцание, особенно в IE/win, поскольку IE имеет собственный эмулятор domready в событии jQuery "ready".