Let's say we're writing a user script which interacts with a 3rd party site we don't control. We want to open a menu, so we trigger a click on the button and then wait 10ms before accessing the menu (which is appended to the document after the click), like this:

$button = $('#button');
setTimeout(function() {
    //access the menu
}, 10);

This works, because it takes less than 10ms for the 3rd party site's handler to appended the menu to the DOM once the button is clicked. But it feels like bad code. Is there a better way to write this?

  • \$\begingroup\$ Better question for StackOverflow. \$\endgroup\$ – Mike Brant Aug 3 '16 at 18:26
  • \$\begingroup\$ @MikeBrant I wasn't sure since my code actually works, it just doesn't "feel" like good code, which is sort of not a "programming" problem, it seems like more of a "coding style" problem. \$\endgroup\$ – Viziionary Aug 3 '16 at 18:30
  • \$\begingroup\$ I think it could be up for interpretation, but the way a look at it is that you need to write a bit of code, that does not yet exist that needs to listen for the onload event for the particular DOM element you are interested in and then trigger click on it. \$\endgroup\$ – Mike Brant Aug 3 '16 at 18:35
  • \$\begingroup\$ @MikeBrant True. The alternate interpretation could be that in lots of great answers on the site, people delete some code and write new code in a way the differs functionally, like the answer below, to demonstrate a better way of writing the same thing. \$\endgroup\$ – Viziionary Aug 3 '16 at 18:40

That's a perfect job for MutationObserver.

new MutationObserver(function(mutations) {
    // access the menu
}).observe($('.immediate-parent-of-the-menu')[0], {childList: true});

$button = $('#button');

The simplest case above works as-is if the menu is added in one mutation, otherwise you'd have to check each of the mutations array elements for addedNodes.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.