pasar para navegador manejadores funciones eventos evento ejemplos javascript json serialization stringify

navegador - eventos para select javascript



Cómo codificar el objeto del evento? (5)

JSON.stringify(eventObject);

da:

TypeError: Converting circular structure to JSON

dojox.json.ref.toJson(eventObject);

da:

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

¿Hay alguna biblioteca / código listo para usar para lograrlo?


Entonces, el problema es JSON.stringify parece rescatar tan pronto como encuentre una referencia circular. De todos modos, no estaba interesado en las propiedades referenciadas circularmente. La forma en que obtuve el resto de ellos es

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

Esto básicamente le dará el resto de las propiedades. Para evitar errores JS puede ponerlo en try / catch.


No estoy seguro de si ayuda, pero acabo de tropezar con esto en la documentación de Angular JS:

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

Ahora podrías hacer algo como:

JSON.stringify(simpleKeys(eventObject));


No podrá serializar un objeto de evento con JSON.stringify, porque un objeto de evento contiene referencias a nodos DOM, y el DOM tiene referencias circulares por todas partes (por ejemplo, relaciones hijo / padre). JSON no puede manejar esto de forma predeterminada, por lo que tiene un poco de suerte allí.

Sugeriría ver ¿Cómo serializar el nodo DOM a JSON incluso si hay referencias circulares? que tiene algunas sugerencias sobre cómo serializar un nodo DOM. Además, las siguientes preguntas parecen tener información útil:

Las bibliotecas JSON capaces de manejar referencias circulares parecen ser

Alternativamente, puede eliminar todas las referencias a los nodos DOM si no los necesita, y luego serializar el objeto. No deberías hacer esto después de todo. Ver el comentario de @PointedEars :)


Tuve un problema similar y escribí un serializador simple de eventos con un método auxiliar para limpiar el atributo de ruta del evento. El enfoque para esta solución para transformar datos del evento en un objeto serializable:

  • Copia sobre atributos primitivos
  • Copie outerHTML para atributos de elemento en el objeto de evento
  • Calcular la ruta del selector para el atributo path (esto evita copiar el outerHTML de la página HTML completa)

// 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>


Use la función "replacer" para evitar errores:

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