传单标记事件在错误的时间触发

IT技术 javascript leaflet
2021-02-26 03:14:26

我正在使用传单 (v 0.7.7) 并且我有一个 Ajax 调用,它获取一些服务器数据以可点击文本标签的形式绑定到我的地图。在我绑定从服务器获得的 JSON 数据的循环中,我有以下代码:

var item_name = L.marker([data.X, data.Y],
{
    icon: L.divIcon(
    {
        className:'MapTag', 
        iconAnchor: [10, 10],
        html:'<img src="/Images/Map/Item' + data.Id + '.png">' + data.Name 
    })
}).on('click', onItemClick(data.Id));

item_layer.addLayer(item_name);

在其他地方,我有 onItemClick 代码:

function onItemClick(item_id)
{
    alert(item_id);
}

现在,好消息是,如果我注释掉其中的事件绑定部分,循环就会完成,并且传单的行为会正常。但是,当我绑定 click 事件时,事情变得很奇怪。为我绑定的集合中的每个项目触发一次事件。当数据从服务器加载时,我每次通过带有当前项目 ID 的循环都会弹出一个警报。感觉它是被“onload”而不是“onclick”触发的。最重要的是,它也不会在加载后注册 divIcons 上的点击。

一定有什么我在这里失踪了,但我看不到它是什么。有什么建议?

这个问题类似于(传单中的标记,点击事件

解决方案: 我将 divIcon 声明的最后一行更改为:

}).on('click', function(e){ alert(data.Id); });

这现在按预期工作。我猜测奇怪的绑定行为是由于未绑定定义的方法引用和传单在其事件管理代码中具有某种功能崩溃。

我保留了“e”参数,因为它是传单文档显示的内容。我没有使用它,但如果其他人复制粘贴它,他们可能需要它。

1个回答

您混淆了函数引用和函数调用的概念,并且您没有对项目 ID进行闭包

如果你声明这个:

function onItemClick(id) { alert(id); }

这将打印对函数的引用:

console.log( onItemClick );

这将打印调用该函数的返回值(因为它不返回任何内容,这等于undefined):

console.log( onItemClick(5) );

所以当你这样做时:

L.marker(....).on('click', onItemClick(id) );

该函数被调用,并on()接收该函数的返回值,即:

L.marker(....).on('click', undefined );

您想要做的是有一个返回函数的函数

function onItemClick(id) { return function(){ alert(id); } }

这样,当你做

L.marker(....).on('click', onItemClick(5) );

这将进行一个函数调用,并使用返回值,现在看起来像这样:

L.marker(....).on('click', function() { alert(5); } );
哇,脑洞大开。我看了几个小时,你过来把它钉好。感谢您的帮助。
2021-04-20 03:14:26
不 - 闭包的重点是通过定义自己的变量范围来防止这种情况发生。我建议你阅读关于闭包的文档——我知道它们很难掌握。
2021-04-22 03:14:26
我刚刚注意到一件事。因为我们映射到点击事件的函数是一个闭包,当我把这段代码放到一个循环中时,所有的items都映射到了同一个Id。(所有项目都查看 Id,循环终止后它是最后一个 Id)我试图将函数调用作为字符串写出到标签,以便每个传单标签不持有对相同值的引用。我需要重新思考这个问题。
2021-04-23 03:14:26