Как устранить пост-рендер "мерцание"? - PullRequest
15 голосов
/ 21 января 2009

Я старался изо всех сил быть пуристом с использованием техник Javascript / Ajax, гарантируя, что все поведение Ajax-y является расширением базовой функциональности, в то время как сайт также полностью функционирует, когда Javascript отключен. Однако это вызывает некоторые проблемы.

В некоторых случаях узел DOM должен быть виден только в том случае, если в браузере включен 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) вызывается только после полной загрузки и рендеринга страницы - следовательно, кнопка отправки первоначально отображается, и «flash» происходит, когда Javascript выполняется, и отображение узла установлено в «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; }

Эта вторая строка только для справки и может (и должна) быть удалена, чтобы избежать обстоятельств, при которых ваш элемент не должен отображаться: блок. Точно так же вам могут потребоваться другие варианты третьей строки для других стилей отображения. Но это решение красивое и чистое, IMO, и в моих тестах полностью исключает эффект мерцания.

Ответы [ 6 ]

10 голосов
/ 21 января 2009

Как насчет объединения некоторых из этих решений:

<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>
5 голосов
/ 21 января 2009

В ситуациях, идентичных вашей, я обычно помещаю кнопку отправки вокруг тега <noscript>. Никто не предлагал этого, поэтому я не уверен, считается ли это плохой практикой в ​​этих областях, но это то, что я использую, и это работает для меня.

Если вы хотите, чтобы узел был виден только при включенном Javascript, вы можете сделать это в заголовке:

<noscript>
    <style type="text/css">
    .js-enabled { display: none; }
    </style>
</noscript>

А затем присвойте любым элементам только для Javascript класс js-enabled.

2 голосов
/ 21 января 2009

Как сказал Дэвид, вы можете добавить 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) правила.

1 голос
/ 21 января 2009

Просто мысль: я не уверен, сработает ли это, но вы можете попробовать вставить Javascript в заголовок документа, чтобы написать элемент стиля CSS, который бы скрывал кнопку.

1 голос
/ 21 января 2009

Я могу придумать два метода:

1 - Предварительно определить, включен ли Javascript, и сохранить эту информацию в файле cookie / сеансе. Это можно сделать на первой странице и устранить большинство мерцаний.

2 - Используйте плагин livequery , который обнаруживает элементы при их добавлении в DOM. Вы можете запустить его правильно, когда Javascript закончит загрузку, что должно быть намного раньше документа (он находится в заголовке).

$('.with_js_disabled').livequery(function() {
     $(this).hide();
});
0 голосов
/ 18 ноября 2009

Попробуйте просто: добавьте <script>jQuery.ready();</script> непосредственно перед закрытием тега body.

Это заставит все привязки к событию «готово» сработать. И если вы запускаете их в конце документа, DOM загружается и готов к работе, даже если «родное» событие onDomContentLoaded еще не сработало.

Это обычно работает для меня, когда я хочу убрать мерцание, особенно в IE / win, так как IE имеет свой собственный эмулятор domready в событии jQuery 'ready'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...