微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有 event.target 的 WeakMap

如何解决带有 event.target 的 WeakMap

编辑:事实证明,第二个片段(我的真实代码)实际上没有任何问题。在一个页面上它可以工作,而在另一个页面上却没有。是的,对于潜在的错误

我正在创建一个 DOM 元素并将该 DOM 元素作为键提供给 WeakMap。然后,使用 JQuery 事件委托/事件侦听器,我试图检索保存的键,但它返回未定义:

const item = document.createElement("div"),__data = new WeakMap();
__data.set(item,{hello: "123"})
document.body.appendChild(item)

// later on in event delegation
$("div").on("click",function(event) {
const target = event.target,data = __data.get(target);
console.log(data)
// prints undefined

有谁知道为没有 ID 的 DOM 元素保存数据有什么问题或替代方法吗?

编辑:我有点恼火我制作的示例有效但我自己的代码没有......(有些看起来多余。这是根据我的实际代码建模的,所以并非所有缺失的部分都在这里,只是务实)但这里是明显的工作代码

const __data = new WeakMap();

function buildingItem() {
  const item = document.createElement("div");
  item.setAttribute("data-action","delete");
  __data.set(item,{hi: 123});
  return item;
}

function build() {
  const main = document.getElementById("main")
  for (let i = 0; i < 3; i++) {
    const container = document.createElement("div"),attached = document.createElement("div");
    const build = buildingItem(),data = __data.get(build);
    build.classList.add("classified");
    data["hello"] = `Item ${i}`
    __data.set(build,data);
    build.innerText = `Item ${i}`
    attached.append(build);
    container.append(attached);
    main.append(container);
  }
}
build()
$(document).on("click","div.classified[data-action]",function(event) {
const target = event.currentTarget,data = __data.get(target);
console.log(`CTarget Data: ${data["hello"]}`)
})
<div id="main"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

解决方法

两个可能的问题:

  1. target 是被点击的最内层元素。您可能需要 thisevent.currentTarget,这是您在其上挂钩事件处理程序的元素(它可能是 target 的祖先元素)。

  2. 您的 jQuery 代码在 所有 div 元素上连接了 click 事件,不仅仅是那个,但您在 {{ 中只有那个 div 1}}。如果您单击不同 div,您自然会得到WeakMap,因为另一个undefined 不是地图中的键。

这是一个示例(我在地图中的 div 中添加了一个 span 以演示 #1,还添加了第二个 div 以演示 #2):

div
const item = document.createElement("div"),__data = new WeakMap();
__data.set(item,{hello: "123"});
document.body.appendChild(item);
item.insertAdjacentHTML("beforeend","<span>Click me,I'll work</span>");
document.body.insertAdjacentHTML("beforeend","<div>Click me,I won't work (I'm not a key in the map)</div>");

$("div").on("click",function(event) {
    const target = event.currentTarget,data = __data.get(target);
    console.log("with currentTarget:",data);
    
    // Note that using `event.target` wouldn't hav eworked
    console.log("with target:",__data.get(event.target));
});

您已经在实际代码中提到您正在使用事件委托。 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>currentTarget 在这种情况下也很好:

this
// Event delegation
$(document.body).on("click","div.example",function(event) {
    const data1 = __data.get(event.currentTarget);
    console.log("using currentTarget:",data1);
    const data2 = __data.get(this);
    console.log("using this:",data2);
});

// Adding the relevant `div`
const item = document.createElement("div"),{hello: "123"});
item.className = "example";
item.textContent = "Some text to make div clickable";
document.body.appendChild(item);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。