字符串化事件对象有效,但实际上是空的

问题描述 投票:4回答:1

我有这个自定义stringify函数,可以处理循环引用:

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

但如果我用它来串化一个事件对象:

  window.addEventListener('click', function (ev) {   // MouseEvent
    const v = customStringify(ev);  // {"isTrusted":true}
  });

v只是字符串,如下所示:

{"isTrusted":true}

太奇怪了。我尝试了一些其他自定义字符串化辅助函数,它们都给了我相同的结果。

我看了这个帖子:How to stringify event object?

但我的问题似乎更具体。

javascript json dom
1个回答
3
投票

JSON.stringify忽略了不可枚举的属性,而MouseEvent的大多数属性(显然)都是不可枚举的:

document.querySelector('button').addEventListener('click', ev => {
  let props = ['isTrusted', 'target', 'clientX', 'clientY', 'layerX', 'layerY'];
  props.forEach(prop => {
    console.log(prop + '?', ev.propertyIsEnumerable(prop));
  });
});
<button>Try it!</button>

您可以按名称调出每个属性,并在将事件移交给JSON.stringify之前使其可枚举:

document.querySelector('button').addEventListener('click', ev => {
  let props = ['target', 'clientX', 'clientY', 'layerX', 'layerY'];
  props.forEach(prop => {
    Object.defineProperty(ev, prop, {
      value: ev[prop],
      enumerable: true,
      configurable: true
    });
  });
  console.log(JSON.stringify(ev));
});
<button>Try it again!</button>
© www.soinside.com 2019 - 2024. All rights reserved.