简体   繁体   English

带有 event.target 的 WeakMap

[英]WeakMap with event.target

Edit: turns out nothing is actually wrong with the second snippet (my real code).编辑:结果证明第二个片段(我的真实代码)实际上没有任何问题。 On one page it works, and on another it doesn't.在一个页面上它有效,而在另一个页面上它没有。 Yea for underlying errors.是的,对于潜在的错误。

I'm creating a DOM element and giving that DOM element to a WeakMap as a key.我正在创建一个 DOM 元素并将该 DOM 元素作为键提供给 WeakMap。 Then, with JQuery event delegation/event listener, I'm trying to retrieve the saved key but it's returning undefined:然后,使用 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

Anyone know what's wrong or an alternative method to save data for a DOM element that doesn't have an ID?任何人都知道为没有 ID 的 DOM 元素保存数据的问题或替代方法吗?

Edit: I'm kinda annoyed that the example I made works but my own code doesn't... (some bits look redundant. This is modeled after my actual code, so not all the missing pieces are here, just pragmatically) but here's the apparently working code:编辑:我有点恼火我做的例子有效,但我自己的代码没有......(有些位看起来多余。这是根据我的实际代码建模的,所以并不是所有丢失的部分都在这里,只是务实)但是这是显然有效的代码:

 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>

Two possible issues:两个可能的问题:

  1. target is the innermost element that was clicked. target是被点击的最里面的元素。 You probably want this or event.currentTarget instead, which is the element on which you hooked the event handler (which may be an ancestor element to target ).您可能需要thisevent.currentTarget ,它是您挂钩事件处理程序的元素(可能是target的祖先元素)。

  2. Your jQuery code hooks up the click event on all div elements, not just that one, but you only have that one div in the WeakMap .您的 jQuery 代码连接了所有div 元素上的click事件,而不仅仅是那个,但您在WeakMap中只有一个div If you click a different div, you'll naturally get undefined because that other div isn't a key in the map.如果您单击不同的 div,您自然会得到undefined ,因为其他div不是 map 中的键。

Here's an example (I've added a span within the div we have in the map to demonstrate #1, and also added a second div to demonstrate #2):这是一个示例(我在 map 的div中添加了一个span来演示#1,还添加了第二个div来演示#2):

 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>

You've mentioned that in your real code you're using event delegation.您已经提到,在您的真实代码中,您正在使用事件委托。 currentTarget and this are both fine in that case as well: currentTargetthis在这种情况下都很好:

 // 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"), __data = new WeakMap(); __data.set(item, {hello: "123"}); item.className = "example"; item.textContent = "Some text to make div clickable"; document.body.appendChild(item);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM