Is IE not allowing a script to interact with created DOM elements?

Hi all,
I’m tearing some hair out.

I’m rewriting a site and one of the things I’d like to do is keep it valid (I can’t make this accessible, not even simply, to save my life).

Our old/current site has these goofy addThis icons. Near as I can tell, the old page calls an external addThis script in the <head> (which is minimised and therefore unreadable), which created an iframe for something (not sure what). Also, the old pages have a bunch of addThis-specific HTML which is both invalid and ugly. The script fills these elements with spans and attributes so that the user gets a bunch of social networking icons to click (mouse only).
One of the new sites I have set up like the old sites, with the bogus HTML hand-written into the page:

[noparse]http://stommepoes.nl/Jeansselling/jeansselling2/artikel.html[/noparse]
(sorry for the unclickable but even changing the settings here did not stop the forums from adding titles to these)


    <script type="text/javascript" src="js/jquerylightbox.js"></script>
    <script type="text/javascript">
      $(function() {
          $('.thumbs a').lightBox({fixedNavigation:true});
      });
    </script>
    <script type="text/javascript" src="js/artikelForms.js"></script>
    [b]<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=foobar"></script>[/b]
</head>

So, that last script is the addThis script. And in the HTML is


<div class="addthis_toolbox addthis_default_style"><a class="addthis_button_email" href=""></a>
<a class="addthis_button_twitter"></a>
<a class="addthis_button_hyves"></a>
<a class="addthis_button_googlebuzz"></a>
<a class="addthis_button_facebook"></a><span class="addthis_separator">|</span>
<a href="http://www.addthis.com/bookmark.php?v=250&amp;username=foobar" class="addthis_button_expanded">Meer</a></div>

[ot]
Yeah, anchors without hrefs. The script adds hrefs to some of the anchors, but not for mail or twitter. So you see I’ve added for mail to make it focusable with keyboard, but twitter can’t have that because the script also adds target=“_blank” which means OUR page opens in a new window/tab.[/ot]

So if I’m writing a valid version of this site, I thought I’d just have Javascript add the bogus HTML for me, since it’s completely useless without Javascript anyway.

Since there’s already a lightbox.js that needs jQuery, I fudged my way around adding bogus HTML with it (looks to me like innerHTML basically).
Another page has an example of this:


    [b]<script type="text/javascript" src="js/jquerylightbox.js"></script>[/b]
    <script type="text/javascript">
      $(function() {
          $('.thumbs a').lightBox({fixedNavigation:true});
      });
     [b] $(function() {
          $('.artikel').append('<div class="addthis_toolbox addthis_default_style"><a class="addthis_button_email" href=""></a><a class="addthis_button_twitter"></a><a class="addthis_button_hyves"></a><a class="addthis_button_googlebuzz"></a><a class="addthis_button_facebook"></a><span class="addthis_separator">|</span><a href="http://www.addthis.com/bookmark.php?v=250&amp;username=jeansselling" class="addthis_button_expanded">Meer</a></div>');
      });[/b]
    </script>
    <script type="text/javascript" src="js/artikelForms.js"></script>
    [b]<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=foobar"></script>[/b]

But, doing this meant the icons didn’t show up in IE (7 or 8… I don’t have 9 and didn’t bother checking 6). I can verify that my script is indeed loading the HTML, but the addThis script isn’t doing anything with it. But, while trying out IE’s debugger, I did get icons. This told me the script was running possibly before the bogus HTML was added.

So I thought I’d be clever and have the same script who’s creating the bogus HTML create the script as well, since this should mean one gets executed first and then the other one.
Don’t have a page doing this but it was something like


    <script type="text/javascript" src="js/jquerylightbox.js"></script>

    <script type="text/javascript">
      $(function() {
          $('.thumbs a').lightBox({fixedNavigation:true});
          $('.artikel').append('<div class="addthis_toolbox addthis_default_style"><a class="addthis_button_email" href=""></a><a class="addthis_button_twitter"></a><a class="addthis_button_hyves"></a><a class="addthis_button_googlebuzz"></a><a class="addthis_button_facebook"></a><span class="addthis_separator">|</span><a href="http://www.addthis.com/bookmark.php?v=250&amp;username=foobar" class="addthis_button_expanded">Meer</a></div>');
         [b] var scriptZ = document.createElement('script');
          scriptZ.type = 'text/javascript';
          scriptZ.src = 'http://s7.addthis.com/js/250/addthis_widget.js#username=foobar';
          $('head').append(scriptZ);[/b]
      });
    </script>
    <script type="text/javascript" src="js/artikelForms.js"></script>

I’m not familiar enough with jQuery to tell if I can stuff everything in one function like that, but I did try with separate ones too.
I also tried appending the script to the body. No dice.

Now this got the script interacting with the bogus HTML in IE! Meaning, I got icons to appear!
But Opera broke. Opera no longer let the script interact with the icons, and only the inserted HTML appeared.
Firefox seems fine with any way I do it. For some reason.

And, while I thought I had IE working, I still didn’t: I tested the Twitter button by logging into twitter in another tab and then clicking the icon. Instead of sending
“Name of item” “some tiny url” via @addThis
(like it does in FF)
it sends
Undefined via @addThis

So, I can’t read the addThis code, can’t tell which end is up there or see how it grabs the correct information in IE.

But the script and the way the icons works ALL the time in ALL browsers if I have the dodgy HTML just sitting in the source by default. Which I don’t want, for two reasons:
-users without Javascript get some retarded link that means nothing and none of the social button thingies
-it’s invalid and I can’t make it valid.

So I’m guessing a lot of this has to do with timing and firing but I can’t follow it in Dragonfly nor in the IE debugger as it just seems to jump into either the jQuery stuff or the addThis stuff and then just ends.

Also, found out trying to add the script to the end of the page with jQuery sucks balls cause I can’t see it in generated source. So to check that I’m actually loading the addThis script, I have this:

[noparse]http://stommepoes.nl/Jeansselling/jeansselling2/artikel-combo.html[/noparse]

where at the bottom I have


  </div>
  <script type="text/javascript">
    alert('IE FOO');
    alert(document.body.lastChild);
  </script>
  <script id="addThis" type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=jeansselling"></script>
</body>
</html>

The script loads, definitely after the bogus HTML is added to the DOM (and it is, I can see it in IE), but it doesn’t add all the spans and icon images to it like it does if that HTML were in the source.

Does anyone have any idea why this is happening? What am I missing?

And no, I really don’t know jQuery and wouldn’t be using it except that the lightbox needs it.

Maybe this will help. You can run the minimised code through jsbeautifier.org toreturn it back to beautifully indented code.
The resulting code still needs more expressive variable names, but it’s enough to get started with.

If you want help with either of those linked pages though, you might have to clarify the problem that the page is having, and what you would like to have done about it.

Maybe this will help. You can run the minimised code through jsbeautifier.org toreturn it back to beautifully indented code.
The resulting code still needs more expressive variable names, but it’s enough to get started with.

omigod, a prettyprint for JS!

If you want help with either of those linked pages though, you might have to clarify the problem that the page is having, and what you would like to have done about it.

Either the icons don’t appear, or they appear and don’t work. Everything works fine IF I leave addThis’ garbage HTML in my source, but what I would like is to be able to take those OUT of my source and just have Javascript add them to the DOM onload.

If I only add them to the DOM via JS and then call the addThis script with script tags in my source code, IE does not let the addThis script interact with the DOM elements: no icons appear. All other browsers are fine.

If I have the DOM-adding script also create and add in the addThis script as well, the IE does show the icons, but Opera doesn’t, and IE does not make the icons work correctly.

That last bit might be a whole separate problem, but if I could get all browsers to at least show the icons, I can go from there.

Still, I’ll see if that prettyprinter gives me any clues. I still think the addThis script is just running in IE and Opera before the new DOM elements are added, since that’s the most likely source of the problem.

An interesting data-point is that the icons all appear when you refresh the page.
If you click on the address bar and press enter, the icons won’t appear. If you hit the refresh button, the icons do appear.

Is it possible to setup a timeout after you load in the first script, that watches for the availability of the elements you are adding, so that only after they are available does the second script get added as well.

Or, modify the second script so that it only runs when you explicitly call an init function, and run that on page load or at some other appropriate time.

An interesting data-point is that the icons all appear when you refresh the page.

More interesting, they don’t show in my copy of IE8 no matter how I refresh:
enter at address bar
F5
ctrl+F5
refresh button

Is it possible to setup a timeout after you load in the first script, that watches for the availability of the elements you are adding, so that only after they are available does the second script get added as well.

I’m probably going to try something like that, yes. I was assuming that listing the append(DOM elements) first and then the <script> tag with addThis script meant one had to finish before the next one ran… and this must be wrong (in IE anyway).

Might not fix IE’s issue with how the buttons work, but I’m quite sure this will always make the buttons load in all browsers.
Thanks for looking at this.

Whoops, I’m running IE9 now.

IETester seems to be even more inconsistent with them for IE8.

Arg, ok I can’t use setTimeout.

I think what I need is a way to test that the elements I’m adding to the DOM are there before adding/calling/running the external addThis script. Or having a listener that waits until those elements have been completely added to the DOM.

Is there a “load” event I can listen for across browsers for DOM elements??
Or some other way people use to “test if dynamic content was added”?

I’m duckduckgo-ing around but I must be using the wrong terms.

All elements support the onload event. For example, when you attach a function to the onload event of an image, that onload event will trigger when the image has loaded.

Hm, unfortunately in jQuery land (or maybe everywhere?) only things with URLs get a load event. I don’t speak jQuery so the best I can do is wander around jQuery.com and look for things that look like they’re related to what I’m looking for. I spent way too long on a page called “load” which apparently looks identical to “load” but is for loading stuff instead of checking to see if stuff loads. Arg.

So I added a BS 1px by 1px image at the end of my divs I’m adding… and after a few hiccups, icons appear in IE and Firefox. But Opera only loads the elements (same problem as before), it doesn’t run the script I call from addThis’ servers. Following the script in Dragonfly didn’t tell me anything… it just kept skipping through a bunch of jQuery stuff and then ends. No errors.

For testing only, this is what I have:
HTML


    <script type="text/javascript" src="js/jquerylightbox.js"></script>
    <script type="text/javascript" src="js/addStuff.js"></script>
  </head>

So, I’m calling the jQuery library (I hate calling 500 scripts so I just tacked the lightbox junk on the end, so that’s why it’s called jquerylightbox instead of jquery.min.js), and then a script called [url=http://stommepoes.nl/Jeansselling/jeansselling2/js/addStuff.js]addStuff.js:


//add invalid DOM elements
$(function() {
    $('.artikel').append('<div class="addthis_toolbox addthis_default_style"><a class="addthis_button_email" href=""></a><a class="addthis_button_twitter"></a><a class="addthis_button_hyves"></a><a class="addthis_button_googlebuzz"></a><a class="addthis_button_facebook"></a><span class="addthis_separator">|</span><a href="http://www.addthis.com/bookmark.php?v=250&amp;username=foo" class="addthis_button_expanded">Meer</a></div>[b]<img id="blank" src="blank.png">[/b]');

//load the script from addThis that's supposed to Do Stuff with above DOM elements, but only after they've loaded
    $('#blank').bind('load', function() {
        var addThisScript = document.createElement('script');
        addThisScript.type = 'text/javascript';
        addThisScript.src = 'http://s7.addthis.com/js/250/addthis_widget.js#username=foo';
        $('body').append(addThisScript);
       //alert(addThisScript.src);
    });      
});

All browsers are loading the DOM elements. However Opera is either not adding the script (which I can’t check, since jQuery apparently removes scripts it adds, making debugging insanely difficult) OR it’s not running it. I can’t tell which.

IE7 and 8 eventually load the icons (yay), but try to tweet “undefined” still (arg). Again, if I put the invalid DOM stuff in my source, they tweet correct information.

[ot]I’m really starting to get irritated that I’m doing all these unsuccessful acrobatics just to keep garbage out of my code. No wonder people leave garbage on the web when including widgets: the widgets are too hard to fight against unless you are as good at scripting as the widget-makers are bad at it.

What’s worse, MY company is basically “supporting” these people by using their crappily-written product. Arg.[/ot]

I feel your pain. If you go to the events category you can find it there.
.load() – jQuery API

Yeah I did eventually find the right one (actually, someone else sent it to me: “You idiot, that’s load the function not load the event!!” lawlz). That’s where I discovered this line:

This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.

So that’s why I added an image. I feel dirty doing that though. All I ever wanted was to know if my DIV and children was loaded… and a p0ny. And a million euros.

I got something to work. In all browsers. Though IE still complains in either an alert (if you have that on) or quietly in the bottom bar (“Done, but with errors on page.”)

[noparse]http://www.addthis.com/help/client-api[/noparse]

mentions a parameter called “domready” which, when I read the description it seems counterintuitive (it’s not so much that I need it assume it’s been added after the DOM was loaded, rather I wanted it to certainly wait until the DOM was loaded) but adding it let both the icons appear AND it seems to be necessary in getting IE to tweet something other than “Undefined”.

I’m not sure what all’s what but I did remember an iFrame was being loaded by the script and IE is funky with something called DOMContentLoaded (which I’m still unclear if this is something that runs after everything called in the source is loaded or also anything dynamically loaded after that) and further searching led to that addThis page where someone had linked to it specifically mentioning IE. Arg.

So this is the code I ended up with (I also tried getting just one script to dynamically load a bunch of others just to cut down requests):

in the HTML:


    <script type="text/javascript" src="js/init.js"></script>
  </head>

init (yeah I saw this on That Smith and thought, cool!):


(function(scripts,src) {
    for(src in scripts) {
        document.writeln('<scri'+'pt src="'+scripts[src]+'" type="text/javascript"></sc'+'ript>')
    }
})
(['js/jquerylightbox.js','js/addStuff.js', 'js/artikelForms.js',[b]'http://s7.addthis.com/js/250/addthis_widget.js#username=foobar&amp;domready=1'[/b]]);

So first loads the jQuery and lightbox stuff, so that my addThis.js (in list above) could run.
My addThis.js:


$(function() {
    $('.artikel').append('<div class="addthis_toolbox addthis_default_style"><a class="addthis_button_email" href=""></a><a class="addthis_button_twitter"></a><a class="addthis_button_hyves"></a><a class="addthis_button_googlebuzz"></a><a class="addthis_button_facebook"></a><span class="addthis_separator">|</span><a href="http://www.addthis.com/bookmark.php?v=250&amp;username=jeansselling" class="addthis_button_expanded">Meer</a></div>');

[b]    var addThisScript = document.createElement('script');
    addThisScript.type = 'text/javascript';
    addThisScript.src = 'http://s7.addthis.com/js/250/addthis_widget.js#username=jeansselling&amp;domready=1';
    $('body').append(addThisScript);  [/b]   
});

Yeah, see how I’ve got it in there twice? If I take out the call from the init.js, Opera dies (Opera maybe loads it too quickly there? It’ll only show the added DOM elements). If I take out the manual building of it from my addThis.js, IE sends “Undefined” to Twitter.

I lost too much hair on this, and I’m happy to let IE users (and I guess not IE9?) get an error that doesn’t seem to mean anything.
Aaaaaaaaaaaaaaaaaaaaaaaaaaaargg.

This means beer.