event.target 的 WeakMap
WeakMap with event.target
编辑:事实证明第二个片段(我的真实代码)实际上没有任何问题。在一个页面上它可以工作,而在另一个页面上则不能。是的,存在潜在错误。
我正在创建一个 DOM 元素并将该 DOM 元素作为键提供给 WeakMap。然后,使用 JQuery 事件 delegation/event 侦听器,我试图检索保存的密钥,但它返回未定义:
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>
两个可能的问题:
target
是被点击的 最里面 元素。您可能需要 this
或 event.currentTarget
,这是您挂钩事件处理程序的元素(它可能是 target
的祖先元素)。
您的 jQuery 代码在 所有 div 元素上连接 click
事件,而不仅仅是那个,但是 WeakMap
中只有那个 div
。如果您单击一个 不同的 div,您自然会得到 undefined
,因为另一个 div
不是地图中的键。
这是一个示例(我在地图中的 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>
您已经提到在您的真实代码中您正在使用事件委托。 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>
编辑:事实证明第二个片段(我的真实代码)实际上没有任何问题。在一个页面上它可以工作,而在另一个页面上则不能。是的,存在潜在错误。
我正在创建一个 DOM 元素并将该 DOM 元素作为键提供给 WeakMap。然后,使用 JQuery 事件 delegation/event 侦听器,我试图检索保存的密钥,但它返回未定义:
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>
两个可能的问题:
target
是被点击的 最里面 元素。您可能需要this
或event.currentTarget
,这是您挂钩事件处理程序的元素(它可能是target
的祖先元素)。您的 jQuery 代码在 所有 div 元素上连接
click
事件,而不仅仅是那个,但是WeakMap
中只有那个div
。如果您单击一个 不同的 div,您自然会得到undefined
,因为另一个div
不是地图中的键。
这是一个示例(我在地图中的 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>
您已经提到在您的真实代码中您正在使用事件委托。 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>