À quoi sert une balise <script> à l'intérieur d'une balise <noscript>?

139

Récemment, j'ai participé à une frénésie de «vue source» sur des sites Web avec un design et un contenu intéressants. L'un de ces sites Web, Squarespace , contient des blocs de <script>balises à l'intérieur d'une <noscript>balise, comme ceci:

<!-- Page is at: http://squarespace.com -->
...
...
<noscript id="inline-deps">
  <link rel="stylesheet" type="text/css" href="//cloud.typography.com/7811972/758964/css/fonts.css" />

  <script type="text/javascript" src="https://static.squarespace.com/static/ta/5134cbefe4b0c6fb04df8065/7400/assets/logomark/logomark.min.js?37"></script>
  <link rel="stylesheet" href="https://static.squarespace.com/static/ta/5134cbefe4b0c6fb04df8065/7400/assets/logomark/logomark.min.css?37" type="text/css" />
</noscript>
...
...

Cela m'a semblé étrange et m'a fait chercher des informations sur Google pour voir s'il y avait une sorte de fonctionnalité / but caché pour un si étrange morceau de HTML, mais en vain. Y a-t-il une sorte de but à avoir des <script>balises à l'intérieur des <noscript>éléments, ou est-ce juste un exemple de mauvais HTML?

Agent.Logic_
la source
18
IMHO cela n'a aucun sens et c'est juste une erreur.
Sebastien C.
12
C'est peut-être juste une façon étrange de commenter JS.
AlexR
8
A en juger par le fait qu'ils ont un en- tête complet (y compris <base href="">, <meta … />, <title>et <link … />éléments) on dirait qu'ils abusent <noscript>pour templating.
Bergi
2
Excellente question! Mais horrible parce que vous avez maintenant lancé une autre frénésie de "vue source" pour moi .. Je viens de sortir de cette habitude!
Bobo
2
@Bobo: Mais regarder le code pour comprendre ce qui se passe à l'intérieur de la matrice est une bonne chose! ;)
Agent.Logic_

Réponses:

139

J'ai fait quelques recherches dans leur code et j'ai trouvé cet extrait (je l'ai nettoyé pour le rendre plus lisible):

var DepLoader = (function () {
  function init() {
    var dependencies = document.getElementById("inline-deps");
    if (!dependencies || JS.hasClass(document.body, "deps--loaded")) {
      webfontsReady();
    } else {
      var html = dependencies.innerText || dependencies.textContent;
      JS.addClass(document.body, "deps--loaded");
      processRaw(html);
    }
  }

  function isListed(a, b) {
    for (var i = 0; i < b.length; i++) {
      if (a.indexOf(b[i]) !== -1) {
        return true;
      }
    }
    return false;
  }

  function webfontsReady() {
    JS.fireCustom("webfontsReady");
  }

  function processRaw(html) {
    var el = document.createElement("div");
    el.innerHTML = html;

    var scripts = el.querySelectorAll("script");
    var styles = el.querySelectorAll("link");
    var common, signup, dialog, systemPage, commerce;
    var others = [];
    var inline = [];
    var styleWhiteList = ["site.css", "dialog-", "signup-", "logomark"];
    var scriptBlackList = ["management-", "ckeditor-"];

    for (var i = 0; i < styles.length; i++) {
      var style = styles[i];
      if (style.href.indexOf("fonts.css") !== -1) load(style, webfontsReady);
      if (isListed(style.href, styleWhiteList)) load(style);
    }

    for (var i = 0; i < scripts.length; i++) {
      var script = scripts[i];
      var src = script.src;

      if (!src && script.getAttribute("data-sqs-type") !== "dynamic-assets-loader" && script.innerHTML.indexOf("SQUARESPACE_ROLLUPS") === -1) {
        eval(script.innerHTML);
      }
    }

    if (window.SQUARESPACE_ROLLUPS) {
      for (var key in SQUARESPACE_ROLLUPS) {
        var rollup = SQUARESPACE_ROLLUPS[key];
        var js = rollup.js;
        var css = rollup.css;

        if (key.indexOf("common") !== -1) {
          common = js;
        } else if (key.indexOf("commerce") !== -1) {
          commerce = js;
        } else if (key.indexOf("signup") !== -1) {
          signup = js;
        } else if (key.indexOf("dialog") !== -1) {
          dialog = js;
        } else if (key.indexOf("system-page") !== -1) {
          systemPage = js;
        } else if (key) {
          others = others.concat(js);
        } else {
          inline = inline.concat(js);
        }
      }
    }

    for (var i = 0; i < scripts.length; s++) {
      var script = scripts[i];
      var src = script.src;

      if (!isListed(src, scriptBlackList)) {
        if (src.indexOf("common-") !== -1) {
          common = script;
        } else if (src.indexOf("commerce-") !== -1) {
          commerce = script;
        } else if (src.indexOf("signup-") !== -1) {
          signup = script;
        } else if (src.indexOf("dialog-") !== -1) {
          dialog = script;
        } else if (src.indexOf("system-page-") !== -1) {
          systemPage = script;
        } else if (src) {
          others.push(script);
        } else {
          inline.push(script);
        }
      }
    }

    function loadOthers() {
      for (var i = 0; i < inline.length; i++) {
        if (inline[i].getAttribute("data-sqs-type") !== "dynamic-assets-loader") {
          load(inline[a]);
        }
      }

      for (var i = 0; i < others.length; i++) {
          load(others[i]);
      }

      JS.fireCustom("dependenciesLoaded");
    }

    var loadSystemPage = load.bind(this, systemPage, loadOthers, "system page");
    var loadSignup = load.bind(this, signup, loadSystemPage, "signup");
    var loadCommerce = load.bind(this, commerce, loadSignup, "commerce");
    var loadDialog = load.bind(this, dialog, loadCommerce, "dialog");
    var loadCommon = load.bind(this, common, loadDialog, "common");

    loadCommon();
  }

  function load(tag, callback, label) {
    var head = document.head;

    if (Array.isArray(tag)) tag = { nodeName: "SCRIPT", src: tag[0] };

    if (!tag) {
      if (callback) callback();
      return;
    }

    if (tag && (tag.src || tag.href)) {
      var child;
      if ("SCRIPT" === tag.nodeName) {
        child = document.createElement("script");
        child.src = tag.src;

        if (child.src.indexOf("combo") !== -1) {
          callback = function () {
            Y.Squarespace.FrontSite.Core.domReady(true)
          };
        }
      } else {
        if ("LINK" === tag.nodeName && "stylesheet" === tag.rel) {
          child = document.createElement("link");
          child.href = tag.href;
          child.rel = "stylesheet";
          child.tyle = "text/css";
        }

        if (child) {
          child.onload = callback;
          head.appendChild(child);
        }
      }
    } else {
      try {
        eval(tag.innerHTML);
      } catch (e) {}
    }
  }

  return { init: init, webfontsReady: webfontsReady };
})();

Comme vous pouvez le voir, la <noscript>balise a l'ID #inline-deps, qui est référencé dans le code (ligne 3) pour charger les dépendances de manière asynchrone et à la demande.

Ils utilisent probablement un <noscript>élément car il leur permet d'accéder directement aux éléments du DOM, au lieu d'avoir à le placer dans une chaîne ou un commentaire (que je considère particulièrement mauvais, car les commentaires ne sont pas destinés à des informations réelles), puis à les analyser. Il empêche également l'exécution de scripts et de styles CSS jusqu'à ce qu'ils soient spécifiquement chargés.

Personnellement, je trouve que c'est un abus de la <noscript>balise. Je ne suis même pas sûr que ce soit du code HTML5 valide. L'utilisation d'autres méthodes telles que la déclaration de dépendances dans un objet JavaScript avec un chargeur de script doit être utilisée dans la mesure du possible.

Qantas 94 lourd
la source
71
Ces pirates de code sournois;). J'espère qu'ils l'ont bien documenté, avant qu'un type intelligent ne le supprime «car il ne sert à rien».
Patrick Hofman
6
J'ai vu <script type="text/html">...</script>utilisé dans le même but - quelqu'un a des avantages / inconvénients des deux?
Shai
4
Il est probable que tout ce qui se trouve à l'intérieur <noscript>serait visible pour les utilisateurs non-JavaScript; la plupart des sites ne prennent tout simplement pas en charge ces utilisateurs, mais vous souhaitez également leur montrer un simple message explicatif.
Katana314
8
Ce sont des pratiques
extrêmement
3
Quelqu'un peut-il expliquer ce que fait ce code? .. 86 votes positifs et je n'ai aucune idée de ce qu'est ce code .. Je me sens stupide! ..
Lakshay