【问题标题】:How to hide elements with jQuery before they get rendered?如何在渲染之前使用 jQuery 隐藏元素?
【发布时间】:2011-02-17 13:34:31
【问题描述】:

我想生成带有可以有条件地显示/隐藏的区域(div、spans)的 html 布局。这些区域默认是隐藏的。

如果我在 document.ready 上使用 jquery 调用 .hide() 方法,这些区域可能会闪烁(浏览器呈现部分加载的文档)。所以我在 html 布局中应用了 "display: none" 样式。

我想知道避免闪烁的最佳做法是什么,因为应用“display:none”会破坏封装规则——我知道 jquery 对隐藏/显示做了什么并使用它。如果 jquery 的隐藏/显示实现有一天会改变,我会让整个网站无法运行。

提前谢谢你

【问题讨论】:

    标签: jquery html hidden


    【解决方案1】:

    @安德鲁,

    我知道答案已经被接受,但使用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 就会运行,从而对用户隐藏它。

    【讨论】:

    • 这将工作不闪烁(在所有浏览器中,对于任何页面)都是不真实的......不同的浏览器,取决于它们的确切实现和页面的大小,最终可能会“闪烁”甚至显示内容一段时间。在 Chrome 中显示一段时间的 EG 示例 (1 MB):architectshack.com/as/BlinkTest.ashx?2
    • 同意 Tao - 这在某些浏览器中不起作用,包括 Chrome。
    【解决方案2】:

    我同意 Boris Guéry 的观点,即这不是过度设计,而是一种标准的最佳实践。我会采取与 Boris 稍有不同的方式,首先在 html 中添加一个 no-js 类,然后使用 JavaScript 将其删除。

    这样,您无需等待文档准备好隐藏内容,并且在没有任何 JavaScript 的情况下您仍然可以看到内容。假设用户没有 JavaScript 更符合渐进增强的理念。

    例如:

    <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');
       }
    );
    

    ********** 或基于个案****************

    例如:

    <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');
    });
    

    【讨论】:

    • +1 我真的很喜欢这个想法。但是使用 CMS 我不能只编辑 html 标签。我想知道是否有其他解决方案。
    • 它不需要是html标签,这只是最广泛的网络。你可以给任何东西添加类吗?如果是这样,那么您可以根据具体情况进行操作,然后在 javascript 中从所有拥有它的对象中删除 .no-js 类。我会用建议更新我的答案。
    • 为了让它工作,我的脚本文件是这样结束的,所以 removeClass() 触发较早,而 show() 触发较晚: $('html').removeClass('no-js '); $(function () { $(window).load(function() { $('#foo').show(); }); });
    • 我不明白。它是如何工作的?您正在像 Andrew 那样使用 document-ready。您正在使用 css 类,他使用 jQuery 的 hide()。为什么你的解决方案更好?
    • CSS 会在页面呈现之前影响页面,而 jQuery 函数在文档实际准备好之前不会被调用。因此,使用 hide() 意味着您会在内容被 javascript 隐藏之前看到闪烁的内容。但是使用 CSS 意味着在您删除该类之前它永远不会显示。
    【解决方案3】:

    我通常为我的元素设置一个 .js 类,以便在启用 javascript 时设置适当的属性。

    然后我可以根据是否存在 javascript 来设置 CSS。

    例如:

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

    我的CSS:

    html.js #foo
    {
        display: none;
    }
    

    和javascript

    $(document).ready(
       function()
       {
         $(html).addClass('js');
       }
    );
    

    【讨论】:

    • 谢谢,但我决定停止选择 simple-css 并发现这种混合(css + javascript)方法对我的任务来说过度设计。
    • 我们的兴趣是为没有 javascript 的人保持可用性和可访问性,如果您将块与其 id 匹配,对于没有启用 javascript 的人来说,它可能会被隐藏。您想了解最佳实践,它最佳实践。
    【解决方案4】:

    设置元素的初始显示属性绝对没有错,尤其是如果您将其封装在 css 类中。

    【讨论】:

    • 如果你这样做,禁用javascript的浏览器将永远不会呈现这些元素
    • 永远,永远,永远,永远。这是不好的做法。
    • 没有“css 类”这样的东西。
    • 当它甚至没有回答标题中的问题时,我不明白为什么这是公认的答案。此外,任何人都可以在下面阅读,此解决方案对于未启用 javascript 的用户来说是无意义的。所以吹这个!
    【解决方案5】:

    【讨论】:

      【解决方案6】:

      为什么不这样做呢?:

      // Hide HTML element ASAP
      $('html').hide();
      
      // DOM-ready function
      $(function () {
         // Do stuff with the DOM, if needed
         // ...
      
         // Show HTML element
         $('html').show();
      }
      

      它似乎工作正常!

      问候。

      【讨论】:

      • 这种方法的问题是它会导致整个页面在页面重新加载时闪烁。如果您有深色背景,则最为明显。
      【解决方案7】:

      您可以在 CSS 类中应用“显示:无”。

      因为浏览器必须读取一些 HTML 代码才能让 JavaScript 找到元素的顺序。您必须将元素标记为隐藏,因为浏览器会读取您的 HTML。

      您也可以在 JavaScript 中插入 HTML,并且可以在呈现之前调用 hide。

      【讨论】:

      • 谢谢,我决定用 CSS 应用 "display: none"
      【解决方案8】:

      这是我的建议。它利用this solution创建一个新的 CSS 规则。主要的事情:如果 JS 可用,将创建一个隐藏一些 html 的 CSS 类,否则不会。这发生在 主要内容(最初应该隐藏的 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。

      【讨论】:

        【解决方案9】:

        经过一段时间的思考,我有了以下解决方案的想法。与我的other solution 相比,我将其简化为基本部分(并使用this 通过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,则默认情况下所有元素都是可见的 - 可以称为 Progressive enhancement

        不确定这是否适用于所有浏览器。但 IMO 这将是一个简单而整洁的解决方案。

        【讨论】:

          【解决方案10】:

          我总是使用 Modernizr.js http://modernizr.com/ 来处理这个问题。

          在 Mondernizr 中,“js”或“no-js”类被添加到页面的 HTML 标记中。

          只有当 html 标记具有 js 类时,您才可以从这里隐藏您的元素。

          Modernizr 非常适合许多其他应用程序,如果您以前没有使用过它,值得一读:http://modernizr.com/docs/

          【讨论】:

            【解决方案11】:

            我总是做的是创建一个空的 div。如果需要显示该组件内的某些数据,我会使用 $.ajax() 将数据(即 html)异步加载到其中。

            不需要额外的库。

            【讨论】:

              【解决方案12】:

              答案有很多,你可以使用 show() 方法并编码条件来显示或隐藏。这是示例代码show_hide when rendering is complete

                <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();
                    }
                });
              
              //});
              

              【讨论】:

                猜你喜欢
                • 2021-04-05
                • 1970-01-01
                • 2022-11-03
                • 2014-08-23
                • 1970-01-01
                • 1970-01-01
                • 2017-07-04
                • 2021-08-11
                • 2014-12-15
                相关资源
                最近更新 更多