6

I have this custom stringify function which can handle circular references:

const customStringify = function (v) {
  return JSON.stringify(v, function(k, v) {
    if (v instanceof Node) {
      return 'Node';
    }
    if (v instanceof Window) {
      return 'Window';
    }
    return v;
  });
};

but if I use it to stringify an event object:

  window.addEventListener('click', function (ev) {   // MouseEvent
    const v = customStringify(ev);  // {"isTrusted":true}
  });

v is just string that looks like this:

{"isTrusted":true}

so bizarre. I tried a few other custom stringifying helper functions, and they all give me the same result.

I looked at this thread: How to stringify event object?

but my problem seems more specific.

3
  • I also looked to see if the MouseEvent has a toJSON method somewhere in the prototype chain, and I didn't see one Commented Jan 2, 2018 at 2:33
  • What are you hoping to accomplish by doing this? Or are you just curious? Commented Jan 2, 2018 at 2:42
  • my goal is to pass event data between threads on the front-end (message passing) Commented Jan 2, 2018 at 4:48

1 Answer 1

3

JSON.stringify ignores non-enumerable properties, and most of the properties of a MouseEvent are (apparently) non-enumerable:

document.querySelector('button').addEventListener('click', ev => {
  let props = ['isTrusted', 'target', 'clientX', 'clientY', 'layerX', 'layerY'];
  props.forEach(prop => {
    console.log(prop + '?', ev.propertyIsEnumerable(prop));
  });
});
<button>Try it!</button>

You can call each property out by name and make it enumerable before handing the event off to JSON.stringify:

document.querySelector('button').addEventListener('click', ev => {
  let props = ['target', 'clientX', 'clientY', 'layerX', 'layerY'];
  props.forEach(prop => {
    Object.defineProperty(ev, prop, {
      value: ev[prop],
      enumerable: true,
      configurable: true
    });
  });
  console.log(JSON.stringify(ev));
});
<button>Try it again!</button>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.