如何字符串化事件对象?(How to stringify event object?)

2019-06-17 11:54发布

JSON.stringify(eventObject);

得到:

TypeError: Converting circular structure to JSON


dojox.json.ref.toJson(eventObject);

得到:

TypeError: Accessing selectionEnd on an input element that cannot have a selection.


有一些库/代码准备用它来完成呢?

Answer 1:

您将无法与序列化的JSON.stringify事件对象,因为一个事件对象包含DOM节点的引用,而DOM有各地的地方(如父/子关系)循环引用。 JSON不能用缺省处理这些,所以你有点运气那里。

我建议看看如何序列化DOM节点JSON即使有循环引用? 这对如何序列化一个DOM节点的一些建议。 此外,下列问题似乎有用信息:

  • 如何保存循环引用的对象?
  • 字符串化(转换为JSON)与循环引用一个JavaScript对象

能够处理循环引用JSON库似乎是

  • JSON-JS(见cycle.js)
  • dojox.json.ref

或者,你可以删除对DOM节点的所有引用如果你不需要它们,然后序列化对象。 你不应该毕竟这样做。 见@PointedEars评论:)



Answer 2:

使用“替代品”的功能,以避免发生错误:

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


Answer 3:

不知道是否有帮助,但我只是在这个角度JS文件中偶然发现:

*资料来源: https://code.angularjs.org/1.5.5/docs/guide/expression#-event-

/*
 * return a copy of an object with only non-object keys
 * we need this to avoid circular references
 */
function simpleKeys (original) {
  return Object.keys(original).reduce(function (obj, key) {
    obj[key] = typeof original[key] === 'object' ? '{ ... }' : original[key];
    return obj;
  }, {});
}

现在,你可以这样做:

JSON.stringify(simpleKeys(eventObject));


Answer 4:

我有一个类似的问题,并写了一个简单的事件串用一个辅助方法来清除事件的路径属性。 这个解决方案从事件到序列化的对象转换数据的方法:

  • 复制过的原始属性
  • 复制outerHTML为元素属性中的事件对象
  • 计算选择路径,路径属性(这避免了复制整个HTML页面的outerHTML)

 // 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: ex, y: ey }; console.log(JSON.stringify(o, null, 2)); } }; // Create a mock event for this example var evt = new MouseEvent("click", { bubbles: true, cancelable: true, view: window }); var cb = document.getElementById("clicker"); // Add a click listener cb.addEventListener("click", serializeEvent); // Fire the event cb.dispatchEvent(evt); 
 <div> <button id="clicker" /> JSONify my click! </div> 



Answer 5:

所以,这个问题是JSON.stringify似乎尽快摆脱困境,为它找到一个循环引用。 我反正不感兴趣,圆引用属性。 我得到了他们的休息方式是

var str = "{"
for (var key in data) {
  if (JSON.stringify(data[key]) !== "") {
    str += key + ":" + data[key]) + ",";
  }
}
str += "}"

这将基本上给你的属性的其余部分。 为避免你可以把如果try / catch语句JS错误。



Answer 6:

只要使用JSON.stringify(事件)和事件数据应该被转换成字符串。



文章来源: How to stringify event object?