Writing HTML in the <head></head> of a page with JS

Hello all,
I know this can be done with media-queries in CSS3, but i was experimenting with some javascript and noticed something odd that I was hoping someone could explain and help me fix.
After attaching the jQuery library, I used js to get the width of the window browser-viewport) and store that in a variable.

What I was aiming to do was write a <title></title> for the page and attach a stylesheet through <link /> using js only when the window’s height was greater than 596px.
So, I wrote the following:


<!Doctype HTML>
<html lang="en">
	<head>
		<script type="text/javascript" src="../assets/js/jquery-1.5.1.min.js"></script>
		<script type="text/javascript">
			$(document).ready(function() {
				var $viewportWidth = null;
				viewportWidth = $(window).width();
				if(viewportWidth > 596){
					document.write("<title>attaching stylesheet in specific viewport-sizes<\\/title>");
					document.write("<link href='bigViewport.css' rel='stylsheet' type='text\\/css' \\/>");
				}
			});
		</script>
	</head>
	<body>
		<h1>Heading!</h1>
		<p>This is a paragraph!</p>
		<p>This is a second paragraph!</p>
		<br />
		<p>This is a paragraph after a line-break</p>
		<form>
			<input type="submit" value="submit" />
		</form>
	</body>
</html>

The content in the body is placeholder content, but the reason i kept it there was to show you all something— as it has to do with the issue I am having.

When I visit the page with just that html above, I assume both lines were written as the page has the title “attaching stylesheet in specific viewport-sizes”. Why I said assume is that i can not see <link /> in the view-source.
Anyway, the problem that occurs is that all of the content in the body is gone. Meaning, nothing shows up on the page— its a blank white-page.
And, as I did, one can double-check that the placeholder-content is there normally if they just comment-out the js.

So my issues are:
1.) Is the <link /> line being written?
2.) Why is all the body’s content gone? And how can i get it to say while writing the html with js in that condition?

document.write creates a brand new page if it runs after the current page finishes loading (as it does with your code).

Why not just use createElement() to create the title and link tags and appendChild() to append them to the head tag. That’s what those JavaScript functions are for.

ah okay. Makes sense why all the previous content is gone.

I didn’t even know there were such functions :blush:

Would the syntax just be or something like:

$(document).ready(function() {
	var $viewportWidth, $title, $link = null;
	viewportWidth = $(window).width();
	if(viewportWidth > 596){
            $title = document.createElement("<title>attaching stylesheet in specific viewport-sizes<\\/title>");
            $link = document.createElement("<link href='bigViewport.css' rel='stylsheet' type='text\\/css' \\/>");
            $("head").appendChild($title);
            $("head").appendChild($link);
        }
}

Or nothing like that at all / was my guess completely off ?

Not far off.

Instead of

$title = document.createElement(“<title>attaching stylesheet in specific viewport-sizes<\/title>”);
$link = document.createElement(“<link href=‘bigViewport.css’ rel=‘stylsheet’ type=‘text\/css’ \/>”);

you would have

$title = document.createElement(“title”);
$title.innerHTML = “attaching stylesheet in specific viewport-sizes”;
$link = document.createElement(“link”);
$link.href = $link = ‘bigViewport.css’;
$link.rel = ‘stylsheet’;
$link.type=‘text/css’ ;

ah okay. Thank you very much!

It’s close. Since you’re using jQuery you can use:


$(function () {
    if ($(window).width() > 596) {
        $('head').append('<title>attaching stylesheet in specific viewport-sizes</title>' +
            '<link href="bigViewport.css" rel="stylesheet" type="text/css" />');
    }
});

You might like to try this approach. I split the original so that the first part gets the width and the second part fires on load and overwrites the content of the <title>. If you want to validate the page you need the title to be in place.


<script type="text/javascript">
    <!--
    var $viewportWidth = $(window).width();
    var $whichCSS=($viewportWidth > 596)? "bigViewport.css" : "smallViewport.css";
     { document.write('<link href="'+$whichCSS+'" rel="stylsheet" title="'+$viewportWidth+'" type="text\\/css" \\/>');  }
    $(document).ready(function() {
      document.getElementsByTagName("title")[0].text="viewport width= "+$viewportWidth+"px"; 
       });
    //-->
    </script>


That will completely overwrite the page.

You should never mix document.write with modern JavaScript.

I don’t know about mixing document.write with “modern” JavaScript, but the way the script is structured does not overwrite the page. This is because I pulled the width detection out of the onload section of the script. This means that it finds the width, writes the <link>, loads the page and then overwrites the <title>. Doing it this way allows the page to be validated before changing the <title> content. Validation will fail if the title is dynamically generated as valdiation of the <head> needs a <title>.

I also found a better way of addressing the title which is jQuery rather than JS. For clarification I have appended the whole page code so that youu can run it yourself.


<!doctype html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta name="GENERATOR" content="Microsoft FrontPage 5.0" />
<meta name="ProgId" content="FrontPage.Editor.Document" />
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
<title>attaching stylesheet in specific viewport-sizes</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js">
    </script>
<script type="text/javascript">
    <!--
    var $viewportWidth = $(window).width();
    var $whichCSS=($viewportWidth > 596)? "bigViewport.css" : "smallViewport.css";
     { document.write('<link href="'+$whichCSS+'" rel="stylsheet" title="'+$viewportWidth+'" type="text\\/css" \\/>');  }
    $(document).ready(function() {
      $(document).attr("title", "viewport width= "+$viewportWidth+"px");
       });
    //-->
    </script>
</head>

<body>

<h1>Heading!</h1>
<p>This is a paragraph!</p>
<p>This is a second paragraph!</p>
<p><br />
This is a paragraph after a line-break</p>
<form action="#">
  <p><input type="submit" value="submit" /></p>
</form>

</body>

</html>