Why do I need to use [removed] instead of DOM mani

2019-06-28 06:54发布

问题:

I'm trying a new ad service, and as far as I know they don't provide a functional interface to loading their ads. We want to display different ad sizes depending on the user's screen size, and this service requires you to load a different .js URL for each size.

I originally tried writing:

<script type="text/javascript"><!--
    var dochead = document.getElementsByTagName('head')[0];
    var newscript = document.createElement('script');
    newscript.type = "text/javascript";
    newscript.src = '//ads-by.madadsmedia.com/tags/22430/9194/async/' + (screen.width >= 1360 ? '160' : '120') + 'x600.js';
    dochead.appendChild(newscript);
    //-->
</script>

but I just got a blank page. I looked in Chrome developer tools and it seemed to be loading their script properly. Their script loads other scripts from Google, and they showed up in the DOM as well. But there was no ad image.

When I changed my script to:

<script language="JavaScript" type="text/javascript">
var prot = document.location.protocol;
var adwidth = (screen.width >= 1360 ? '160' : '120');
document.write('<script language="JavaScript" type="text/javascript"'); document.write('src="'+prot+'//ads-by.madadsmedia.com/tags/22430/9194/async/'+adwidth+'x600.js">'); document.write('<\/scr' + 'ipt>');
</script>

it worked properly. I don't generally like using document.write, I wonder why it's needed in this case? The ad service's script makes extensive use of document.write, is that why?

回答1:

Because they are using document.write():

http://ads-by.madadsmedia.com/tags/22430/9194/async/160x600.js:

if (!window.ActiveXObject){
  document.write("<div style=\"text-align: center; margin: 0px auto; width:160px; height:600px; position:relative;\">");
// etc.

If document.write() isn't run in-line on and actively "open" document, it'll clobber what's there. So, running their script post-load overwrites your content with theirs.



回答2:

if their script uses document.write it is possible that it would cause the page to go blank, as it overwrites the stream.

document.write clears page

You could override document.write as a fix: (but I wouldn't.....)

How to deal with document.write in a script that's added after a page has loaded?



回答3:

if the document is loading its ready state is interactive but the body element has not been completely parsed. You can not add a child to an element which has not been loaded. It results in an error and the script stops.

dochead.appendChild(newscript);

The quick fix is to run your function using a body.onload event. Moving the script to the bottom of the page may work but I would not consider that reliable in a world which includes Internet Explorer and badly behaving browsers.