0

This question has been asked a few times on stackoverflow, but I have yet to come across a solution that suits my unique situation.

I'm looking to replace deprecated code livequery and DOMNodeInserted. Examples shown below.

I’m developing javascript for a 3rd party website we are required to use at work. Therefore, when my script is run the page has loaded and I have no access to the js file on the server. We use IE exclusively, the current version is IE11.

I’ve read here that livequery() is useful in “rare case where you need to respond to DOM changes, and have no control over the jQuery that is causing those changes”. This is my situation exactly.

I am a complete noob with this stuff but I’ve read MutationEvents/Observers can do this, but they are not compatible with IE. What I’ve read is beyond my understanding at this point anyway.

Here is what I am trying to do:

When a user clicks a tab on the 3rd party app, everything on that tab is dynamically created. I need to determine when the tab has finished loading - so I do this by checking for the existence of an element on the tab, and when it is created I know the tab has loaded.

For this example, the tab includes an icon called 's_3_1_12_0_icon'.

Both of these code snippets will trigger the desired result:

//Method 1: Using DOMNodeInserted
$('body').on('DOMNodeInserted', function () {
    var elementExists = document.getElementById('s_3_1_12_0_icon');
    if (elementExists != null) { 
        alert('The element has just been created')
        $('body').off('DOMNodeInserted');
    }
});

//Method 2: Using Livequery
$('#s_3_1_12_0_icon').livequery(function() {
    alert('The element has just been created')
    $('#s_3_1_12_0_icon').expire();
});

But as mentioned, livequery() and DOMNodeInserted are depricated. Is there a modern method of doing this?

ThanosLovesYuna
  • 87
  • 1
  • 1
  • 8

1 Answers1

2

...I’ve read MutationEvents/Observers can do this, but they are not compatible with IE...

IE9 and IE10 both have the old deprecated mutation events (mostly); IE11 has the newer mutation observers. You can definitely use a mutation observer for this.

var observer = new MutationObserver(function() {
  if (document.getElementById('s_3_1_12_0_icon') != null) {
    var p = document.createElement('p');
    p.innerHTML = "It fired!";
    document.body.appendChild(p);
    observer.disconnect();
    observer = null;
  }
});
observer.observe(document.body, {
  childList: true,
  subtree: true
});
setTimeout(function() {
  var div = document.createElement('div');
  div.id = "s_3_1_12_0_icon";
  document.getElementById("descendant").appendChild(div);
}, 600);
<div>
  <div>
    <div id="descendant"></div>
  </div>
</div>
<p>In a moment, we'll add the element and see if the observer fires...</p>

(The divs are just there to demonstrate that it doesn't have to be a direct child of body.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • TJ Crowder - thank you for responding so quickly. Is there any reason why I am getting "MutationObserver is undefined" error? – ThanosLovesYuna Mar 23 '15 at 20:32
  • @ThanosLovesYuna: You need to make sure IE11 isn't crippling itself. If you're testing with an intranet site, it probably is, because IE's mind-bogglingly-stupid default setting is to use "compatibility" mode with intranet URLs, disabling modern features. Add `` to the `head` (very near the top, ideally just after ``) to tell it it's okay to be, you know, fully there. [More here](https://www.modern.ie/en-us/performance/how-to-use-x-ua-compatible). (And happy to help.) – T.J. Crowder Mar 23 '15 at 20:49
  • @ TJ Crowder:you are correct, this is an intranet site. I tried this: `$('head').append('');` but that didn't work. Could it be because this is a 3rd party site, all the stuff in `` gets loaded prior to my js being executed? – ThanosLovesYuna Mar 23 '15 at 21:03
  • @ThanosLovesYuna: The meta tag has to be there when the page is *parsed*, you can't add it later. Your other alternative is to modify the IE setting: Go to the gear menu then choose "Compatibility view settings..." and untick the "Display intranet sites in compatibility view" checkbox (or just have users do it for that specific page by clicking the weird icon that IE shows when rendering in compatibility view). You can also update this via Active Directory, though I have no idea how. – T.J. Crowder Mar 23 '15 at 21:13
  • Thanks again for your help. As luck would have it, "Display intranet sites in compatibility view" is not checked off and It's greyed out, meaning our IT wants it that way. So I tried `document.getElementsByTagName('head')[0].appendChild('');` which worked but gave me a HierarchyRequestError. When I check the 3rd party app, I see this: ``. I imagine this is causing the error. – ThanosLovesYuna Mar 23 '15 at 21:36
  • @ThanosLovesYuna: Yes. IE8, 9, and 10 don't have `MutationObserver`, and IE11 with that X-UA-Compatible setting will work in IE10 mode. If you can't win the X-UA-Compatible war with the product (I would *seriously* contact them to complain, that header is just dumb, it should be `IE=edge`), you can use use a mutation observer polyfill that provides the `MutationObserver` interface using the old mutation events. Search for "mutation observer polyfill" (there are several) and look for one that uses mutation events. – T.J. Crowder Mar 24 '15 at 08:08
  • 1
    @TJCrowder - Thanks for the time and patients with this. I now understand a lot more about the environment I am forced to work in. This ridiculous environment aside, you've answered the question perfectly and when I do complain to the 3rd party app about `X-UA-Compatible` and have them use `IE=Edge`, I will implement the solution you've provided. Cheers – ThanosLovesYuna Mar 24 '15 at 14:33