How to stringify event object? How to stringify event object? json json

How to stringify event object?


You won't be able to serialize an event object with JSON.stringify, because an event object contains references to DOM nodes, and the DOM has circular references all over the place (e.g. child/parent relationships). JSON can't handle these by default, so you're a bit out of luck there.

I'd suggest to look at How to serialize DOM node to JSON even if there are circular references? which has a few suggestions on how to serialize a DOM node. Also, the following questions seem to have useful information:

JSON libraries able to handle circular references seem to be

Alternatively, you could delete all references to DOM nodes if you don't need them, and then serialize the object. You shouldn't do this after all. See @PointedEars comment :)


Use the "replacer" function to avoid errors:

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

Update 2019: the browser API has changed some way, here is a method to expose all available keys in Event prototype chain

function stringifyEvent(e) {  const obj = {};  for (let k in e) {    obj[k] = e[k];  }  return JSON.stringify(obj, (k, v) => {    if (v instanceof Node) return 'Node';    if (v instanceof Window) return 'Window';    return v;  }, ' ');}


I had a similar problem and wrote a simple event serializer with a helper method to cleanup the event's path attribute. The approach for this solution to transform data from the event to a serializable object:

  • Copy over primitive attributes
  • Copy outerHTML for element attributes in the event object
  • Calculate selector path for the path attribute (this avoids copying the outerHTML of the entire HTML page)

// Calculate a string representation of a node's DOM path.var pathToSelector = function(node) {  if (!node || !node.outerHTML) {    return null;  }  var path;  while (node.parentElement) {    var name = node.localName;    if (!name) break;    name = name.toLowerCase();    var parent = node.parentElement;    var domSiblings = [];    if (parent.children && parent.children.length > 0) {      for (var i = 0; i < parent.children.length; i++) {        var sibling = parent.children[i];        if (sibling.localName && sibling.localName.toLowerCase) {          if (sibling.localName.toLowerCase() === name) {            domSiblings.push(sibling);          }        }      }    }    if (domSiblings.length > 1) {      name += ':eq(' + domSiblings.indexOf(node) + ')';    }    path = name + (path ? '>' + path : '');    node = parent;  }  return path;};// Generate a JSON version of the event.var serializeEvent = function(e) {  if (e) {    var o = {      eventName: e.toString(),      altKey: e.altKey,      bubbles: e.bubbles,      button: e.button,      buttons: e.buttons,      cancelBubble: e.cancelBubble,      cancelable: e.cancelable,      clientX: e.clientX,      clientY: e.clientY,      composed: e.composed,      ctrlKey: e.ctrlKey,      currentTarget: e.currentTarget ? e.currentTarget.outerHTML : null,      defaultPrevented: e.defaultPrevented,      detail: e.detail,      eventPhase: e.eventPhase,      fromElement: e.fromElement ? e.fromElement.outerHTML : null,      isTrusted: e.isTrusted,      layerX: e.layerX,      layerY: e.layerY,      metaKey: e.metaKey,      movementX: e.movementX,      movementY: e.movementY,      offsetX: e.offsetX,      offsetY: e.offsetY,      pageX: e.pageX,      pageY: e.pageY,      path: pathToSelector(e.path && e.path.length ? e.path[0] : null),      relatedTarget: e.relatedTarget ? e.relatedTarget.outerHTML : null,      returnValue: e.returnValue,      screenX: e.screenX,      screenY: e.screenY,      shiftKey: e.shiftKey,      sourceCapabilities: e.sourceCapabilities ? e.sourceCapabilities.toString() : null,      target: e.target ? e.target.outerHTML : null,      timeStamp: e.timeStamp,      toElement: e.toElement ? e.toElement.outerHTML : null,      type: e.type,      view: e.view ? e.view.toString() : null,      which: e.which,      x: e.x,      y: e.y    };    console.log(JSON.stringify(o, null, 2));  }};// Create a mock event for this examplevar evt = new MouseEvent("click", {  bubbles: true,  cancelable: true,  view: window});var cb = document.getElementById("clicker");// Add a click listenercb.addEventListener("click", serializeEvent);// Fire the eventcb.dispatchEvent(evt);
<div>  <button id="clicker" /> JSONify my click!</div>