Cain Nuke
Cain Nuke

Reputation: 3103

How to trigger a javascript function on appearence of an element

Hi,

I need to execute a javascript function once as soon as an element with a given class appears on the code (the element will be generated by another script).

This is my function:

play(sound);

the element would appear inside this:

<div id="canvas">

The element would look like this:

<span class="sound">sound name</span>

where "sound name" will determine the argument for play();

how can this be done with javascript?

Thank you.

Upvotes: 1

Views: 854

Answers (3)

acdcjunior
acdcjunior

Reputation: 135812

You can use a You could use a MutationObserver as shown below.

The second argument to .observe(), MutationObserverInit, is important:

In the options, use childList: true if the span will only be added as a direct child. subTree: true if it can be at any level down below #canvas.

From the docs:

  • childList: Set to true if additions and removals of the target node's child elements (including text nodes) are to be observed.
  • subtree: Set to true if mutations to target and target's descendants are to be observed.

$("#go").click(function () {
    $("#canvas").append($('<span class="sound">sound name</span>'));
});

function play(n) { alert('playing '+ n); }

var obs = new MutationObserver(function(mutations, observer) {
  $.each(mutations, function (i, mutation) {
    var addedNodes = $(mutation.addedNodes);
    var selector = "span.sound"
    var spanSounds = addedNodes.find(selector).addBack(selector); // finds either added alone or as tree
    spanSounds.each(function () { // handles any number of added spans
      play($(this).text());
    });
  });
});

obs.observe($("#canvas")[0], {childList: true, subtree: true});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="canvas"></div>

<button id="go">Add span to canvas</button>


Using plain JavaScript

The code is a little less compact, but it is definitely doable:

document.getElementById("go").addEventListener('click', function () {
  var s = document.createElement('span');
  s.innerText = 'sound name';
  s.classList.add('sound')
  document.getElementById('canvas').appendChild(s);
});

function play(n) { alert('playing '+ n); }

var obs = new MutationObserver(function(mutations, observer) {
  for(var i=0; i<mutations.length; ++i) {
    for(var j=0; j<mutations[i].addedNodes.length; ++j) {
      var addedNode = mutations[i].addedNodes[j];
      //NOTE: if the element was added as child of another element, you would have to traverse
      // the addedNode to find it. I recommend the jQuery solution above if that's the case
      if(addedNode.tagName == "SPAN" && addedNode.classList.contains("sound")) {
        play(addedNode.innerText);
      }
    }
  }
});

obs.observe(document.getElementById('canvas'), {childList: true, subtree: true});
<div id="canvas"></div>

<button id="go">Add span to canvas</button>

Upvotes: 2

August
August

Reputation: 2113

You need a listener to detect the DOM change, MutationObserver

// Select the node that will be observed for mutations
var targetNode = document.getElementById('some-id');

// Options for the observer (which mutations to observe)
var config = { attributes: true, childList: true };

// Callback function to execute when mutations are observed
var callback = function(mutationsList) {
    for(var mutation of mutationsList) {
        if (mutation.type == 'childList') {
            console.log('A child node has been added or removed.');
        }
        else if (mutation.type == 'attributes') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
        }
    }
};

// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

// Later, you can stop observing
observer.disconnect();

Upvotes: 0

Simon
Simon

Reputation: 113

You could probably try onload event

Upvotes: 0

Related Questions