I've been on a "view source" spree lately on websites with interesting design and content. One of those websites, Squarespace, has blocks of <script>
tags inside of a <noscript>
tag, like so:
<!-- 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>
...
...
It struck me as odd, and got me googling for info to see if there's some kind of hidden functionality/purpose for such an odd bit of HTML, but to no avail. Is there some kind of purpose to having <script>
tags inside of <noscript>
elements, or is this just an example of bad HTML?
Definition and Usage The <noscript> tag defines an alternate content to be displayed to users that have disabled scripts in their browser or have a browser that doesn't support script. The <noscript> element can be used in both <head> and <body>.
- Prevents scripts on the page from executing.
The Script element is used in the HTML file for using the JavaScript in the code. The Noscript element is used to display the alternate text on the browser that does not support scripts.
I did some searching through their code and found this snippet (I've cleaned it up to make it more readable):
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 };
})();
As you can see, the <noscript>
tag has the ID #inline-deps
, which is referenced in the code (line 3) to load dependencies asynchronously and on-demand.
They probably use a <noscript>
element as it allows them to directly access DOM elements, instead of having to place it in a string or a comment (which I consider particularly bad, as comments are not meant for actual information) and then parse it. It also prevents the execution of scripts and CSS styles until specifically loaded.
I personally find this an abuse of the <noscript>
tag. I'm not even sure if it's valid HTML5 code. Using other methods such as declaring dependencies in a JavaScript object with a script loader should be used where practicable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With