0

I'm trying to create another event type extending the $.event.special object. Because I need to change an element different from input type. The problem is that when I launch the page the console gives me this error:

main.js:5 Uncaught TypeError: Cannot read property 'mutationsLists' of undefined

The script is this:

(function($){

 $.event.special.changeElement = {
    eventType: 'changeElement',
    mutationObserver : new MutationObserver($.event.special.changeElement.mutationsLists),

    setup: function(data, namespaces) {
      var config = { attributes: true, childList: true };
      $.event.special.changeElement.mutationObserver.observe(this, config);
    },

    teardown: function(namespaces) {
      $.event.special.changeElement.mutationObserver.disconnect();
    },

    handler: function(event) {
      event.type = $.event.special.changeElement.eventType;
      return $.event.dispatch.apply(this, arguments);
    },

    mutationsLists : 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.');
          }
      }
    }

  }

})(jQuery);

I checked and it looks that $.event.special.changeElement is defined, but looks undefined when a call its members...

Salvio
  • 100
  • 2
  • 15

1 Answers1

0

mutationLists is a property of $.event.special.changeElement which is a function. Having properties as functions of an object acts as a function expression meaning that is is not defined until the code is reached. For an example of this, see this jsFiddle.

You will see in that fiddle that firstFunction can call secondFunction as it is defined before it. However, secondFunction cannot call thirdFunction as it is not defined before firstFunction is invoked.

For a rectification to your issue, define the function mutationLists before you define the property mutationObserver.

wmash
  • 4,032
  • 3
  • 31
  • 69
  • I tried this too, it doesn't work. The only thing that works it's to call mutationList as an external function. – Salvio Mar 15 '18 at 17:40
  • As you are within the same scope of the object to access the reference to the function, you should use 'this' keyword. For example, this.mutationLists – wmash Mar 15 '18 at 17:47
  • I made this too... when I made a console.log of this I saw that is a window object... – Salvio Mar 15 '18 at 17:53
  • Why is it needed to create an instance of MutationObserver within the object? As you mentioned, why can you not just instantiate it after the object had been defined? – wmash Mar 15 '18 at 18:26
  • Oh ok. But how can I get the handle to launch it??? I tried with $._data(this, "events") but how can I get the handle that I pass with $(...).on('changeElement', f....)? I need to launch f after the mutation of the dom... – Salvio Mar 15 '18 at 18:58
  • You mentioned when you logged 'this', a window object was returned, correct? By this definition (https://stackoverflow.com/questions/2518421/jquery-find-events-handlers-registered-with-an-object), '$._data(this, "events")' would not work as the 1st argument to '_data' needs to be a HTML element – wmash Mar 15 '18 at 23:00