이벤트 개체를 문자열화하는 방법
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.
이를 위해 사용할 수 있는 라이브러리/코드가 있습니까?
이벤트 개체에는 DOM 노드에 대한 참조가 포함되어 있고 DOM에는 순환 참조가 곳곳에 있기 때문에 이벤트 개체를 JSON.stringify로 직렬화할 수 없습니다(예: 자식/부모 관계).기본적으로는 JSON은 이러한 문제를 처리할 수 없기 때문에 그쪽에서는 운이 좀 떨어집니다.
순환 참조가 있는 경우에도 DOM 노드를 JSON에 직렬화하는 방법을 살펴보는 것이 좋습니다.여기에는 DOM 노드의 시리얼화 방법에 대한 몇 가지 제안이 포함되어 있습니다.또, 다음의 질문에도 도움이 되는 정보가 있는 것 같습니다.
순환 참조를 처리할 수 있는 JSON 라이브러리는 다음과 같습니다.
또는 필요 없는 경우 DOM 노드에 대한 모든 참조를 삭제한 다음 개체를 직렬화할 수 있습니다.
결국 이러면 안 돼.@PointedEars 코멘트를 참조해 주세요.
에러를 회피하려면 , 「리플레이서」기능을 클릭합니다.
JSON.stringify(evt, function(k, v) {
if (v instanceof Node) {
return 'Node';
}
if (v instanceof Window) {
return 'Window';
}
return v;
}, ' ');
업데이트 2019: 브라우저 API가 다소 변경되었으며, 이벤트 프로토타입 체인에서 사용 가능한 모든 키를 노출하는 방법이 있습니다.
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;
}, ' ');
}
비슷한 문제가 발생하여 이벤트의 경로 속성을 정리하기 위해 도우미 메서드를 사용하여 간단한 이벤트 직렬화기를 작성했습니다.이 솔루션에서는 데이터를 이벤트에서 시리얼 가능한 개체로 변환합니다.
- 기본 특성 위에 복사
- 외부 복사이벤트 객체의 요소 속성을 위한 HTML
- 패스 아트리뷰트의 셀렉터 패스를 계산합니다(이것에 의해, 외부 복사가 회피됩니다).HTML 페이지 전체의 HTML)
// 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>
Alexander Shutau가 제공한 코드의 개량된 버전으로, 이 코드에서는 멀티 레벨 오브젝트(ES6)가 처리됩니다.
function stringify_object(object, depth=0, max_depth=2) {
// change max_depth to see more levels, for a touch event, 2 is good
if (depth > max_depth)
return 'Object';
const obj = {};
for (let key in object) {
let value = object[key];
if (value instanceof Node)
// specify which properties you want to see from the node
value = {id: value.id};
else if (value instanceof Window)
value = 'Window';
else if (value instanceof Object)
value = stringify_object(value, depth+1, max_depth);
obj[key] = value;
}
return depth? obj: JSON.stringify(obj);
}
그냥 이렇게 불러주세요.
stringify_object(event, 2);
예를 들어 터치스타트 이벤트에서 다음과 같은 메시지가 나타납니다.
touchstart : {"isTrusted":true,"touches":{"0":{"identifier":0,"target":{"id":"screen"},"screenX":548,"screenY":281.5,"clientX":498.1817932128906,"clientY":185.90908813476562,"pageX":498.1817932128906,"pageY":185.90908813476562,"radiusX":29.77272605895996,"radiusY":27.954544067382812,"rotationAngle":0,"force":0.5},"length":1,"item":{}},"targetTouches":{"0":{"identifier":0,"target":{"id":"screen"},"screenX":548,"screenY":281.5,"clientX":498.1817932128906,"clientY":185.90908813476562,"pageX":498.1817932128906,"pageY":185.90908813476562,"radiusX":29.77272605895996,"radiusY":27.954544067382812,"rotationAngle":0,"force":0.5},"length":1,"item":{}},"changedTouches":{"0":{"identifier":0,"target":{"id":"screen"},"screenX":548,"screenY":281.5,"clientX":498.1817932128906,"clientY":185.90908813476562,"pageX":498.1817932128906,"pageY":185.90908813476562,"radiusX":29.77272605895996,"radiusY":27.954544067382812,"rotationAngle":0,"force":0.5},"length":1,"item":{}},"altKey":false,"metaKey":false,"ctrlKey":false,"shiftKey":false,"view":"Window","detail":0,"sourceCapabilities":{"firesTouchEvents":true},"which":0,"initUIEvent":{},"NONE":0,"CAPTURING_PHASE":1,"AT_TARGET":2,"BUBBLING_PHASE":3,"type":"touchstart","target":{"id":"screen"},"currentTarget":{"id":"screen"},"eventPhase":2,"bubbles":true,"cancelable":true,"defaultPrevented":false,"composed":true,"timeStamp":192516.7899999651,"srcElement":{"id":"screen"},"returnValue":true,"cancelBubble":false,"path":{"0":{"id":"screen"},"1":{"id":"back"},"2":{"id":""},"3":{"id":""},"4":{},"5":"Window"},"composedPath":{},"stopPropagation":{},"stopImmediatePropagation":{},"preventDefault":{},"initEvent":{}}
도움이 될지는 모르겠지만 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));
그래서 문제는 JSON.stringify가 순환 참조를 발견하자마자 빠져나가는 것 같다는 것입니다.나는 어쨌든 순환적으로 참조되는 특성에는 관심이 없었다.내가 나머지를 얻는 방법은
var str = "{"
for (var key in data) {
if (JSON.stringify(data[key]) !== "") {
str += key + ":" + data[key]) + ",";
}
}
str += "}"
그러면 기본적으로 나머지 속성이 제공됩니다.JS 오류를 피하기 위해 try/catch에 넣을 수 있습니다.
JSON.stringify(이벤트)만 사용하면 이벤트 데이터를 문자열로 변환할 수 있습니다.
언급URL : https://stackoverflow.com/questions/11547672/how-to-stringify-event-object
'sourcetip' 카테고리의 다른 글
Oracle에서 활성/열린 연결을 나열하는 방법 (0) | 2023.04.03 |
---|---|
숫자를 "인덱스"(JSON)로 사용 (0) | 2023.04.03 |
스프링 테스트에서 @EnableScheduling 비활성화 (0) | 2023.03.29 |
MVC vs. 플럭스 ? 양방향 vs.단방향? (0) | 2023.03.29 |
Spring boot .jar internal /lib에 외부 라이브러리 .jar를 추가합니다. (0) | 2023.03.29 |