简体   繁体   中英

Can I load data on a web page statically, unless JavaScript is enabled?

Let's say that I have a single page site, and I want to wait to load any content below the fold (using ajax) until the user clicks a link to go to that content on the same page. However, I don't want users who have JavaScript disabled to just not see any content below the fold. The whole reason to load the content with ajax is so that the initial page load is faster, so having the content load either way and then hide until the user clicks would be pointless. I'm sure it's possible to only load content if JavaScript is enabled, but is it possible to not load specific "static" or server-side generated content if JavaScript is enabled in the browser?

Is there any way to prevent specific static content from being loaded by the server on initial page load at all if JavaScript is enabled in the browser?

You might consider using the noscript tag.

<body>
  <h1>Above the fold header</h1>
  <video src="fancy-cat.mp4" ... />

  <div id="below-the-fold">
   <noscript>
     <!-- Users with Javascript disabled get this content -->
     <h2>My cat plays piano</h2>
     <video src="piano-cat.mp4" ... />

     <h2>My cat knows how to use the toilet</h2>
     <video src="potty-cat.mp4" ... />
   </noscript>
  </div>

You can then use javascript to copy the contents of these <noscript> tags on page load and insert them into the DOM.

The innerHTML property of a noscript tag will return an encoded string of HTML. But you can use the handy dandy Encoder script to convert it to something the DOM will like.

  <script src="http://www.strictly-software.com/scripts/downloads/encoder.js"></script>
  <script>
    $(window).load(function() {
      // Copy the 'noscript' contents into the DOM
      $("noscript").each(function() {
        $(this).after(Encoder.htmlDecode($(this).html()));
      });  
    });
  </script>
</body>

Alternatively, if the "below the fold" content is really image/video heavy, you might just want to consider Lazy Loading the content.

If you want to avoid loading data in the case of a client with JS enabled, then you might have to combine server-side and client-side techniques.

This could be used as a rough guide. Disclosure - I've not tested any of this!

For example, if your site structure looked like this:

/
    page1.jsp
    fragment1_1.jsp
    fragment1_2.jsp
    page2.jsp
    fragment2_1.jsp
    fragment2_2.jsp
    ...

Then page1.jsp could look like this (apologies if you don't know JSP and jQuery, but this is mostly pseudo-code anyway):

<%!
  // Define a method to help us import fragments into the current page.
  // Conditional import of fragment based on isJSEnabled
  void myImport (String fragment, boolean isJSEnabled, HttpServletResponse res) {
    if (!isJSEnabled) {
      // output fragment contents directly to response
      String contents = // get contents of fragment
      res.getWriter().write(contents);
    }
  }
%>

<%
  // How to work out if JS is enabled on the server-side?
  // Not sure it can be done. So need to be told by the browser somehow.
  // Maybe a request parameter. So if param not present, assume no JS.
  boolean isJSEnabled = (null != req.getParameter("js"));
%>

<html>
<head>
<script>
// Try and redirect to JS version of page as soon as possible,
// if we're not already using the JS version of the page.
// This code does not take into account any existing request parameters for
// the sake of brevity.
// A browser with JS-enabled that was incrementally downloading and parsing
// the page would go to the new URL.
if (window.location.href.indexOf("js=true") < 0) {
  window.location.href += "?js=true";
}
</script>
</head>
<body>
  <h1 class="fragment_header" data-fragment-id="fragment1_1">Fragment 1</h1>

  <div>
  <%
    // Conditionally import "fragment1_1".
    myImport("fragment1_1", isJSEnabled);
  %>
  </div>

  <h1 class="fragment_header" data-fragment-id="fragment1_2">Fragment 2</h1>

  <div>
  <%
    // Conditionally import "fragment1_2".
    myImport("fragment1_2", isJSEnabled);
  %>
  </div>

  <script>
    // For each fragment header, we attach a click handler that loads the
    // appropriate content for that header.
    $(".fragment_header").click(function (evt) {
      var header = $(evt.target);
      // Find the div following the header.
      var div = header.next("div");
      if (div.children().length < 1) {
        // Only load content if there is nothing already there.
        div.load(header.attr("data-fragment-id") + ".jsp");
      }
    });

    $("a").click(function (evt) {
      // Stop the browser handling the link normally.
      evt.preventDefault();

      // Rudimentary way of trying to ensure that links clicked use the
      // js=true parameter to keep us is JS mode.
      var href = anchor.attr("href");
      var isLocalHref = // logic to determine if link is local and should be JS-ified.
      if (isLocalHref) {
        href = href + "?js=true";
      }
      window.location.href = href;
    });
  </script>
</body>
</html>

A user browsing to page1.jsp would get the static version initially, though a JS enabled browser would switch to the JS enabled version as soon as possible.

As we attach click handlers to all the links, we can control the loading of the next page. If JS is switched off at some point, the js=true parameter will not be appended to each href and the user will revert to a static page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM