[英]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:两个可能的问题:
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
).您可能需要this
或event.currentTarget
,它是您挂钩事件处理程序的元素(可能是target
的祖先元素)。
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: 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"), __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.