2012-07-18 7 views
21

JSON.stringify(eventObject);Come stringificare l'oggetto evento?

dà:

TypeError: Converting circular structure to JSON


dojox.json.ref.toJson(eventObject);

dà:

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


C'è qualche libreria/codice pronto all'uso per realizzarlo?

+0

Stai cercando di visualizzare la struttura per estrarre determinati metodi dall'oggetto o qual è il tuo scopo per voler "stringificare" esso? – RobB

+0

debugging PhoneGap - invia strutture dati, eventi e tracce stack al livello nativo – Tar

risposta

14

Non sarà possibile serializzare un oggetto evento con JSON.stringify, poiché un oggetto evento contiene riferimenti a nodi DOM e il DOM ha riferimenti circolari su tutto il luogo (ad esempio relazioni figlio/genitore). JSON non può gestirli di default, quindi sei un po 'sfortunato.

Suggerirei di guardare a How to serialize DOM node to JSON even if there are circular references? che ha alcuni suggerimenti su come serializzare un nodo DOM. Inoltre, le seguenti domande sembrano avere informazioni utili:

librerie JSON in grado di gestire i riferimenti circolari sembrano essere

In alternativa, è possibile eliminare tutti i riferimenti ai nodi DOM se non sono necessari e quindi serializzare l'oggetto. Non dovresti farlo dopo tutto. Vedere @PointedEars commentano :)

+1

Gli oggetti evento sono [oggetti host] (http://ecma-international.org/ecma-262/5.1/#sec-4.3.8). [Non scherzare con loro] (http://ecma-international.org/ecma-262/5.1/#sec-8.6.2), come provare a cancellare le loro proprietà o assegnarle a proprietà che non dovrebbero essere assegnate a. – PointedEars

+0

Grazie per averlo indicato e per i link! – fresskoma

+0

Prego. – PointedEars

2

Non sono sicuro se aiuta, ma ho appena imbattuto in questo nella documentazione angolare JS:

* Fonte: 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; 
    }, {}); 
} 

Ora si potrebbe fare qualcosa di simile:

JSON.stringify(simpleKeys(eventObject)); 
+0

Quando lo si usa su un touchevent, restituisce solo un singolo elemento '{isTrusted: true}'. –

4

utilizzare la funzione "sostituto" per evitare errori:

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

Avevo un problema simile e ho scritto un semplice serializzatore di eventi con un metodo di supporto per pulire l'attributo del percorso dell'evento.L'approccio di questa soluzione per trasformare i dati dall'evento di un oggetto serializzabile:

  • Copy sugli attributi primitivi
  • Copy outerHTML per elemento attributi nell'oggetto evento
  • Calcolare percorso selettore per l'attributo path (questo evita la copia del outerHTML di tutta la pagina 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>

0

Quindi, il problema è JSON.stringify sembra uscire di emergenza non appena trova un riferimento circolare. Non ero comunque interessato alle proprietà referenziate circolarmente. Il modo in cui ho preso il resto è

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

Questo fondamentalmente vi darà il resto delle proprietà. Per evitare errori JS, puoi inserire if in try/catch.

Problemi correlati