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.
それを達成するためにすぐに使用できるライブラリ/コードはありますか?
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.
それを達成するためにすぐに使用できるライブラリ/コードはありますか?
JSON.stringify を使用してイベント オブジェクトをシリアル化することはできません。これは、イベント オブジェクトに DOM ノードへの参照が含まれており、DOM のいたるところに循環参照 (子/親の関係など) があるためです。JSON はデフォルトではこれらを処理できないため、少し運が悪いです。
循環参照がある場合でも、DOM ノードを JSON にシリアル化する方法を確認することをお勧めしますか? これには、DOM ノードをシリアライズする方法に関するいくつかの提案があります。また、次の質問には有用な情報があるようです。
循環参照を処理できるJSONライブラリは
または、DOM ノードへの参照が不要な場合はすべて削除してから、オブジェクトをシリアル化することもできます。結局のところ、これを行うべきではありません。@PointedEarsのコメントを参照してください:)
同様の問題があり、イベントのパス属性をクリーンアップするヘルパー メソッドを使用して単純なイベント シリアライザーを作成しました。イベントからシリアライズ可能なオブジェクトにデータを変換するこのソリューションのアプローチ:
// 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 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>
それが役立つかどうかはわかりませんが、Angular 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));