0

Working on a Mobile First design and want to conditional load and execute some JavaScript based on the browser width.

UPDATE: (more info on what I'm doing)

I'm looking to conditionally load different size Google DFP ads depending on the width of the browser window. So a desktop/iPad might see a 720 pixel wide ad, a wide mobile might see a 480px ad and a basic mobile might see a 320px ad.

Google DFP has an asynchronous method which has the main code in the head. Ad calls are then made via a combination of a div with a numbered id and a function call that has the same number.

So in what I'm trying to accomplish, I need to insert both a numbered div and a specific numbered function call into the div where I want the specific ad call to appear.

Looked around for conditional examples and this worked in my test:

<div id="ad"></div>
<script type="text/javascript">
var ad = document.getElementById("ad");
if (document.documentElement.clientWidth > 640) {
ad.innerHTML = "big";
}
if (document.documentElement.clientWidth < 640) {
ad.innerHTML = "small";
}
</script>

Obviously just a test of the width checking and not the ad call.

If I understand correctly, innerHTML won't work if I need to dynamically load and execute some JavaScript.

Basically, when I test for the size I have to enter an ad call like this into the #ad div:

<div id='div-gpt-ad-xxxxxxxxxxx-2' 
style='width:728px;height:90px;margin:auto'><script type='text/javascript'>
googletag.cmd.push(function() { googletag.display('div-gpt-ad-xxxxxxxxxxx-2'); });
</script></div>

Notice the "-2" in both the div and function. That will be different for the different ad sizes.

Completely new to DOM manipulation so any help is greatly appreciated.

7
  • 1
    Generally, it's easier and faster to just include all the javascript you need for different widths in one JS file (that can be cached by the browser) and then conditionally execute based on run-time conditions. Commented Dec 22, 2011 at 22:52
  • @jfriend00 the only problem is that the Google ad calls require different HTML ids to display the ads, so it's not just a matter of checking the size and calling the function. Commented Dec 22, 2011 at 23:00
  • You can use document.write() to generate the desired HTML at runtime based on the screen size. Commented Dec 22, 2011 at 23:11
  • @jfriend00 I thought I'd read that most people were moving away from document.write due to various issues with performance, etc. Commented Dec 22, 2011 at 23:28
  • It depends upon the limitations of the problem you're solving. Sometimes document.write() is the right tool, sometimes not. We'd have to see your entire page and know the limitations of the google ad code to know if you could do it a different way or not. There are certain types of browser page loading optimizations that cannot be used if document.write() is being used. Commented Dec 22, 2011 at 23:32

2 Answers 2

1

You are correct that script elements inserted using the innerHTML property aren't executed.

A simple solution is to collect the script elements that were inserted and replace them with new elements where the code will be executed, e.g.

function insertAndExecute(id, markup) {

    var sOld, sNew, scripts;
    var s;
    var el = document.getElementById(id);

    if (el) {
        s = document.createElement('script');
        el.innerHTML = markup;
        scripts = el.getElementsByTagName('script');

        for (var i=0, iLen=scripts.length; i<iLen; i++) {
            sOld = scripts[i];
            sNew = s.cloneNode(true);
            sNew.type = sOld.type;

            if (sOld.src) {
                sNew.src = sOld.src;
            } else {
                sNew.text = sOld.text;
            }
            sOld.parentNode.replaceChild(sNew, sOld);
        }
    }
}

It is much better if the scripts have a src attribtue and load an external file.

As jfriend00 says, if you can determine the markup to be inserted during page load, document.write is a viable alternative as it will cause included scripts to be executed. But you can't use it after the page has finished loading.

Edit

As for getting the width of the window:

var width = window.innerWidth || document.body.clientWidth;

should do. Note that in IE, clientWidth is 20px less than the window width because it allows for a vertical scroll bar. But that shouldn't matter here.

Also, clientWidth shouldn't be measured until the document has finished loading so the layout is complete (use onload or something later), and make sure documents have a DOCTYPE so that IE is in standards mode (or "almost standards mode" or whatever).

You might also be interested in How to Measure the Viewport.

Sign up to request clarification or add additional context in comments.

3 Comments

just going to do a few more checks but this seems to have done it. Thanks!
In my test document I was using document.documentElement.clientWidth. Is there a more foolproof solution that will better handle different browsers and platforms?
The size of the browser window is only vaguely related to the device window size in that it will normally be a similar size or smaller, and rarely larger (e.g. in Mac OS it is never taller but might be wider). Anyhow, I usually defer to whatever David Mark uses in his MyLibrary. Get the bits you want, test it thoroughly and you're done.
0

If you're new to DOM manipulation, then stop right now and find a JavaScript library that you like. The DOM is by far the most frustrating part of using JavaScript in the browser, so don't ruin your first experience with the language by not using a library that helps you with it. Two good options are YUI and jQuery. This is important because you can't get the width of the screen reliably with document.documentElement.clientWidth. Different browsers use different properties for it.

Regarding your question, in this case it's just a matter of running the code in your script after inserting the content into the ad container.

<div id="ad"></div>
<script>
  document.getElementById('ad').innerHTML = '<div id="div-gpt-ad-xxxxxxxxxxx-2" style="width:728px;height:90px;margin:auto"></div>';
  if (screenWidth > 640) {
    googletag.cmd.push(function() {
      googletag.display('div-gpt-ad-xxxxxxxxxxx-2');
    });
  } else {
    // do something else
  }
</script>

3 Comments

thanks for the example. I think it needs to be changed though because the id of the "div-gpt..." stuff is different depending on the ad size. i.e. <div id="div-gpt-ad-xxxxxxxxxxx-2" etc needs to go INSIDE the conditional. When I tried that, it didn't seem to work.
just tried the code. It inserted the new div into the ad div but did not execute the function.
Of course a complete newbie will have no idea what a "good" library is or whether it suits their needs. Given the problem, there is absolutely no need for a library since the OP has a very simple issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.