Как скрыть элементы с помощью jQuery до того, как они будут отображены?

Я хочу сгенерировать html-макет с областями (divs, spans), которые можно показывать/скрывать условно. Эти области скрыты по умолчанию.

Если я вызову метод .hide() с jquery для document.ready, эти области могут мигать (браузеры отображают частично загруженные документы). Поэтому я применяю стиль «display: none» в макете html.

Интересно, как лучше всего избегать мигания, потому что применение «display: none» нарушает правило инкапсуляции — я знаю, что jquery делает с скрытием/показом, и использую его. Если реализация скрытия/отображения jquery изменится в один прекрасный день, я получу весь сайт неработоспособным.

заранее спасибо


person Andrew Florko    schedule 10.05.2010    source источник


Ответы (12)


Нет абсолютно ничего плохого в установке начального свойства отображения элемента, особенно если вы инкапсулируете его в класс css.

person James H    schedule 10.05.2010
comment
Если вы пойдете по этому пути, браузер с отключенным javascript никогда не отобразит эти элементы. - person Stéphane; 10.05.2010
comment
Никогда, никогда, никогда, никогда. Это плохая практика. - person Marko; 03.10.2010
comment
Нет такой вещи, как класс css. - person Johannes Pille; 03.12.2015
comment
Я не понимаю, почему это принятый ответ, если он даже не отвечает на вопрос в заголовке. Также, как любой может прочитать ниже, это решение бессмысленно для пользователей без включенного javascript. Так удар это! - person Manticore; 23.06.2016

@Андрей,

Я знаю, что ответ уже принят, но использование display: none; будет кошмаром для пользователей без Javascript.

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

Рассмотрим несколько элементов div, которые должны быть скрыты при загрузке страницы.

<head>
    <script type="text/javascript" src="jQuery.js"></script>
</head>
<body>
    <div id="hide-me">
        ... some content ...
    </div>
    <script type="text/javascript">
        $("#hide-me").hide();
    </script>

    <div id="hide-me-too">
        ... some content ...
    </div>
    <script type="text/javascript">
        $("#hide-me-too").hide();
    </script>
</body>

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

person Marko    schedule 02.10.2010
comment
То, что это будет работать ‹u›без мигания‹/u› (во всех браузерах, для любой страницы), просто неверно... Различные браузеры, в зависимости от их точной реализации и размера страницы, могут в конечном итоге мигать или даже отображать содержание на некоторое время. Образец EG (1 МБ), который некоторое время отображается в Chrome: architectshack.com/as/ BlinkTest.ashx?2 - person Tao; 21.06.2012
comment
Согласен Тао - это НЕ работает в некоторых браузерах, включая Chrome. - person jimasp; 06.01.2014

Я согласен с Борисом Гери, что это не чрезмерная инженерия, а скорее стандартная передовая практика. Я бы пошел немного другим путем, чем Борис, сначала добавив класс без js в html, а затем удалив его с помощью JavaScript.

Таким образом, вы не ждете, пока документ будет готов, чтобы скрыть содержимое, и без JavaScript вы все еще видите содержимое. Предположение, что у пользователя нет JavaScript, больше соответствует философии прогрессивного улучшения.

ex:

<html class="no-js">
<body>
<div id="foo"></div>
</body>
</html>

мой CSS:

#foo {
    display: none;
}
html.no-js #foo {
    display: block;
}

и JavaScript

$(document).ready(
   function()
   {
     $('html').removeClass('no-js');
   }
);

********* ИЛИ в каждом конкретном случае***********

ex:

<div class="no-js" id="foo">foobar and stuff</div>

CSS:

.no-js {
  display:none;
}
#foo {
  display: block;
}
#foo.no-js {
  display: none;
}

js:

$(document).ready(function(){
  // remove the class from any element that has it.
  $('.no-js').removeClass('no-js');
});
person Ryan Ore    schedule 19.01.2012
comment
+1 Мне очень нравится эта идея. Однако, используя CMS, я не могу просто редактировать тег html. Мне интересно, есть ли другое решение. - person Tom; 02.05.2013
comment
Это не обязательно должен быть тег html, он просто создает самую широкую сеть. Можете ли вы добавить классы к чему-нибудь? Если это так, вы можете сделать это для каждого случая, а затем в javascript удалите класс .no-js из всех объектов, которые его имеют. Я обновлю свой ответ предложением. - person Ryan Ore; 02.05.2013
comment
чтобы заставить его работать, мой файл сценария закончился так, поэтому removeClass() срабатывает раньше, а show() срабатывает поздно: $('html').removeClass('no-js'); $(функция () { $(окно).load(функция() { $('#foo').show(); }); }); - person jimasp; 07.01.2014
comment
Я не понимаю. Как это работает? Вы используете готовый документ, как это делает Эндрю. Вы используете классы css, он использует hide() jQuery. Почему ваше решение лучше? - person robsch; 01.05.2016
comment
CSS повлияет на страницу еще до того, как она отобразится, тогда как функции jQuery не вызываются до тех пор, пока документ не будет фактически готов. Таким образом, использование hide() означает, что вы увидите мерцание контента, прежде чем он будет скрыт javascript. Но использование CSS означает, что он никогда не будет отображаться, пока вы не удалите этот класс. - person Ryan Ore; 01.05.2016
comment
Спасибо за ваш ответ! Что произойдет, если JS недоступен? Я пробовал, и мне кажется, что CSS скрывает div. Я не понимаю, зачем это показывать? Посмотрите на эту скрипку и закомментируйте одну строку JS (я предполагаю, что это то же самое, как если бы JS не быть доступным), чтобы увидеть, что содержимое затем скрыто. - person robsch; 02.05.2016
comment
Причины скрыть/показать что-то зависят от ситуации. Если JS не включен, вы можете предложить статическое изображение, а не какую-нибудь милую галерею ajaxy. В противном случае они могут увидеть пустой div... Или, может быть, просто сообщение о том, что им было бы веселее, если бы у них был JavaScript. ... Я думаю, что className 'no-js' сбивает с толку, потому что на самом деле он позволяет вам показывать альтернативный контент, удаляя класс, а не добавляя его. На самом деле называйте вещи так, как они имеют для вас наибольший смысл. - person Ryan Ore; 02.05.2016
comment
Я понимаю. Я добавил еще один ответ, который является более сложным, но, надеюсь, решит все проблемы. - person robsch; 02.05.2016
comment
Хороший подход! Что касается индивидуального подхода, я не понимаю, зачем нужен .no-js {display:none:), поскольку он уже обрабатывается #foo.no-js {display: none;}. Кажется, работает для меня без него. Если бы кто-нибудь мог объяснить, что мне не хватает, я был бы признателен. - person Jeffrey Simon; 09.11.2019

Обычно я устанавливаю класс .js для своего элемента, чтобы установить правильное свойство, когда включен javascript.

Затем я могу установить CSS в зависимости от того, присутствует ли javascript или нет.

ex:

<html class="js">
<body>
<div id="foo"></div>
</body>
</html>

мой CSS:

html.js #foo
{
    display: none;
}

и JavaScript

$(document).ready(
   function()
   {
     $(html).addClass('js');
   }
);
person Boris Guéry    schedule 10.05.2010
comment
Спасибо, но я решил остановить свой выбор на simple-css и нашел этот смешанный (css + javascript) подход переработанным для моих задач. - person Andrew Florko; 10.05.2010
comment
Интерес состоит в том, чтобы сохранить удобство использования и доступность для людей, у которых нет javascript, если вы сопоставите свой блок с его идентификатором, он, вероятно, будет скрыт для людей, у которых не включен javascript. Вы хотели узнать лучшие практики, это ЕСТЬ лучшие практики. - person Boris Guéry; 10.05.2010

Я тоже боролся с этим, особенно в IE, и нашел это очень полезным: http://robertnyman.com/2008/05/13/how-to-hide-and-show-initial-content-взависимостиоттого,доступналиподдержкаjavascript/

person tester testers    schedule 02.10.2010

Почему бы не сделать именно так?:

// Hide HTML element ASAP
$('html').hide();

// DOM-ready function
$(function () {
   // Do stuff with the DOM, if needed
   // ...

   // Show HTML element
   $('html').show();
}

Кажется, работает нормально!

С Уважением.

person Andy    schedule 14.02.2015
comment
Проблема с этим подходом заключается в том, что вся страница мерцает при перезагрузке страницы. Это наиболее заметно, если у вас темный фон. - person meesern; 15.05.2015

вы можете применить «display: none» в классе CSS.

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

Однако вы также можете вставить HTML в свой JavaScript и вызвать скрытие перед его визуализацией.

person Darkerstar    schedule 10.05.2010
comment
Спасибо, я решил применить display: none с помощью CSS - person Andrew Florko; 10.05.2010

Это мое предложение. Он использует это решение для создания нового правила CSS. Главное: класс CSS, который скрывает какой-то html, будет создан, если доступен JS, иначе нет. И это происходит до обработки основного содержимого (с html-частями, которые изначально должны быть скрыты)!

<html>
<head>
    <style>
        /* This class gets overwritten if JS is enabled. If a css file (bootstrap, ...) 
        gets loaded with such a class this would be also overwritten. This solution does 
        not require the class. It is here just to show that it has no effect 
        if JS is activated.*/
        .hidden {
            display: block;
            background: red;
        }
    </style>
    <script>
        // this is copied from the linked stackoverflow reply:
        function setStyle(cssText) {
            var sheet  = document.createElement('style');
            sheet.type = 'text/css';
            /* Optional */
            window.customSheet = sheet;
            (document.head || document.getElementsByTagName('head')[0]).appendChild(sheet);
            return (setStyle = function (cssText, node) {
                if (!node || node.parentNode !== sheet)
                    return sheet.appendChild(document.createTextNode(cssText));
                node.nodeValue = cssText;
                return node;
            })(cssText);
        }

        // And now: This class only gets defined if JS is enabled. Otherwise 
        // it will not be created/overwritten.
        setStyle('.hidden { display: none; }');

        // Attention: Now that the class is defined it could be overwritten 
        // in other CSS declarations (in style tags or with loaded CSS files).
    </script>
</head>
<body>

    <button>Show/Hide</button>

    <div class="">before</div>
    <div class="my-element hidden">
        Content that should be initially hidden if possible.
        You may want to multiply this div by some thousands
        so that you see the effect. With and without JS enabled.
    </div>
    <div class="">after</div>

    <script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
    <script>
        // Here is some 'normal' JS code. Very likely loaded as a JS file:
        $('button').click(function () {
            $('.my-element').toggleClass('hidden');
            // or setting display directly: 
            //   $('.my-element').toggle() 
            // but well, having class hidden though it is not 
            // hidden makes is not so nice...
        })
    </script>

</body>
</html>

Немного сложнее, но я думаю, что это правильное решение. Преимущество заключается в том, что мерцание предотвращается и работает, если JS не включен. И это не требует jQuery.

person robsch    schedule 02.05.2016

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

<html>
<head>
    <style>
        /* This could be also part of an css file: */
        .container-with-hidden-elements .element {
            display: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <script>
            document.getElementsByClassName('container')[0]
                    .className += ' container-with-hidden-elements';
        </script>

        <div class="element">Content that should be initially hidden if possible.</div>
    </div>
</body>
</html>

Тег скрипта выполняется немедленно и добавляет класс в контейнер. В этом контейнере есть несколько вложенных элементов, которые теперь скрыты, потому что у контейнера есть специальный класс и есть правило CSS, которое теперь имеет эффект.

Опять же, это происходит до того, как оставшийся html будет обработан (предотвращает мерцание). А также, если JS отключен, все элементы видны по умолчанию — то, что можно назвать прогрессивным улучшением.

Не уверен, что это работает в каждом браузере. Но ИМО было бы простым и аккуратным решением.

person robsch    schedule 03.05.2016

Я бы всегда использовал Modernizr.js http://modernizr.com/, чтобы справиться с этим.

С Mondernizr к тегу HTML вашей страницы добавляется класс «js» или «no-js».

Отсюда вы можете скрыть свои элементы, только если тег html имеет класс js.

Modernizr отлично подходит для множества других приложений, и о нем стоит прочитать, если вы еще не использовали его: http://modernizr.com/docs/

person Jimbo Jones    schedule 14.03.2014

Что я всегда делаю, так это создаю пустой div. И если необходимо отобразить некоторые данные внутри этого компонента, я асинхронно загружаю в него данные (т.е. html) с помощью $.ajax().

Нет необходимости в дополнительной библиотеке.

person Coen Damen    schedule 30.04.2015

Есть много ответов, вы можете использовать метод show() и кодировать условие для отображения или скрытия. Вот пример кода show_hide после завершения рендеринга

  <div id="banner-message">
  <p id="hello">Hello World!!!!!</p>
  <input id="statusconf" value="" type="checkbox">Show hello world text when i click this check box
  <button>Change color</button>
</div>

    // find elements
var banner = $("#banner-message")
var button = $("button")

// handle click and add class
button.on("click", function(){
  banner.addClass("alt")
})

//Set this up as part of document ready if you wish
//$(document).ready(function(e) {

    $("#statusconf").show(function(e) {
            if ($("#statusconf").is(':checked') === false) {
                $('#hello').hide();
            } else {
        $("#hello").show();
      }
  });

    $("#statusconf").on("click", function(e) {
    if ($("#statusconf").is(':checked') === false) {
                $('#hello').hide();
            } else {
        $("#hello").show();
      }
  });

//});
person webjockey    schedule 09.04.2019