如何将事件对象转化为字符串?

7 浏览
0 Comments

如何将事件对象转化为字符串?

JSON.stringify(eventObject); 的结果是:

TypeError: 将循环结构转换为JSON。


dojox.json.ref.toJson(eventObject); 的结果是:

TypeError: 在无法进行选择的输入元素上访问selectionEnd。


是否有一些可以直接使用的库或代码来完成这个任务?

0
0 Comments

如何将事件对象转化为字符串?

问题的出现原因:

我遇到了类似的问题,并编写了一个简单的事件序列化器,其中包含一个帮助方法来清理事件的路径属性。这个解决方案的方法是将事件的数据转换为可序列化的对象:

1. 复制基本属性

2. 复制事件对象中元素属性的outerHTML

3. 计算路径属性的选择器路径(避免复制整个HTML页面的outerHTML)

解决方法:

以下是一种计算节点DOM路径的字符串表示的方法:

// 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;
};
// 生成事件的JSON版本。
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));
  }
};
// 为这个示例创建一个模拟事件
var evt = new MouseEvent("click", {
  bubbles: true,
  cancelable: true,
  view: window
});
var cb = document.getElementById("clicker");
// 添加点击监听器
cb.addEventListener("click", serializeEvent);
// 触发事件
cb.dispatchEvent(evt);

HTML代码:

这应该是可以接受的答案。是的,根据您的需求,您需要稍微定制内部工作方式,但整体上非常好!如果您想重新创建整个事件,可以对o.eventName进行字符串操作,将o.view替换为一个对象(通常是window),并通过解析o.target来获取目标元素,例如参见这里

0
0 Comments

问题原因:在处理事件对象时,直接使用JSON.stringify()方法会出现一些错误,例如无法序列化Node和Window对象。

解决方法:可以使用"replacer"函数来避免这些错误。在replacer函数中,判断值是否为Node或Window对象,如果是则返回相应的字符串表示,否则返回原值。然后将该replacer函数作为参数传递给JSON.stringify()方法。

在2019年的更新中,浏览器API发生了一些变化,因此可以使用一个新的方法来公开事件原型链中的所有可用键。该方法是通过遍历事件对象的属性,将属性名和属性值存储在一个新的对象中,然后将该对象作为参数传递给JSON.stringify()方法,并使用相同的replacer函数处理Node和Window对象。

然而,这种方法对于MouseEvent对象只能得到{isTrusted: true}的结果,无法获得其他详细信息。因此,可以根据需要创建一个自定义算法,处理循环引用、返回构造函数名称、选择器等其他信息。

0
0 Comments

问题原因:无法使用JSON.stringify方法将事件对象转化为字符串,因为事件对象包含对DOM节点的引用,而DOM具有循环引用(例如,子/父关系)。JSON默认无法处理这些循环引用。

解决方法:建议查看"How to serialize DOM node to JSON even if there are circular references?"这个问题,其中提供了一些关于如何序列化DOM节点的建议。此外,以下问题似乎也包含了一些有用的信息:

- "How to save an object with circular references?"

- "Stringify (convert to JSON) a JavaScript object with circular reference"

能够处理循环引用的JSON库包括:

- "JSON-js (see cycle.js)"

- "dojox.json.ref"

需要注意的是,事件对象是宿主对象。不能对它们进行修改,例如尝试删除属性或赋值给不应赋值的属性。

因此,解决方法是使用上述提到的JSON库来处理循环引用的问题,而不是尝试删除DOM节点的引用再进行序列化。

0