jQuery使用最后一个参数在Javascript循环中单击绑定函数

jQuery click binding function in Javascript loop using last parameter

本文关键字:循环 单击 绑定 函数 Javascript 最后一个 参数 jQuery      更新时间:2024-05-27

这可能是我像往常一样愚蠢。。。但这让我很沮丧。

我有一个遍历多维数组的foreach循环,对于每个项目,我都会在自定义的leafletjs映射中添加一个标记。一切都很好,只是我在标记上有一个自定义的点击事件(它是leafletjs这一事实应该无关紧要),而且它只使用了最后一个传递的参数。

这是代码:

var markerArray = [
    ["aspiration", -55.63342652633955, -54.1953125, "aspiration-high-school", [19, 29], [38, 57], [75, 113], [150, 226], [299, 451], [597, 901]],
    ["bird", 12.89745, 69.99818, "bird", [22, 20], [44, 40], [87, 79], [173, 158], [345, 315], [689, 629]],
    ["camera", -22.908054128088575, -29.15421875, "camera", [15, 22], [29, 44], [57, 88], [113, 176], [225, 351], [450, 702]],
    ["chef", -46.6909603909255, 106.193125, "chef", [12, 54], [23, 108], [45, 215], [90, 430], [179, 859], [358, 1718]],
    ["computer", -57.37383096593114, 92.71484375, "computer", [14, 18], [28, 36], [56, 72], [112, 144], [223, 288], [445, 576]],
    ["film", -25.91792293614603, -43.69140625, "film", [13, 19], [25, 38], [49, 75], [98, 149], [196, 298], [392, 595]],
    ["gotthejob", -0.490228926463384, -61.02343749999999, "got-the-job", [40, 10], [80, 19], [160, 38], [320, 75], [639, 150], [1278, 300]],
    ["headmaster", -8.5, -60.57812500000001, "headmaster", [40, 44], [80, 87], [160, 173], [320, 346], [639, 692], [1278, 1383]],
    ["letter", -78.77138592818217, -57.15, "letter", [13, 11], [26, 21], [51, 42], [101, 83], [202, 166], [404, 331]],
    ["newspaper", -67.64766505841037, 92.6578125, "news-paper", [21, 15], [41, 30], [82, 59], [163, 117], [325, 234], [649, 467]],
    ["openday", -69.69785394109224, 24.3578125, "open-day", [15, 17], [29, 34], [57, 67], [113, 133], [226, 266], [452, 531]],
    ["prospectus", -11.885147283424319, -136.39453125, "prospectus", [37, 57], [74, 113], [148, 226], [295, 452], [590, 904], [1180, 1808]],
    ["ruler", -73.92669969306126, 4.94609375, "ruler", [12, 11], [24, 22], [48, 43], [96, 85], [192, 169], [384, 337]],
    ["schoollogo", 9.64906182688142, -108.50859375, "school-logo", [21, 27], [41, 53], [81, 106], [161, 211], [321, 421], [641, 841]],
    ["schoolplay", -3.013667927566642, -159.54921875, "school-play", [18, 43], [36, 86], [71, 172], [142, 344], [283, 687], [566, 1373]],
    ["sun", 14.98818922264095, 20.26953125, "sun", [40, 18], [79, 36], [158, 72], [316, 143], [631, 285], [1262, 570]],
    ["train", -81.93133285369295, -141.99609375, "train", [42, 30], [83, 60], [165, 119], [330, 237], [659, 473], [1317, 946]]
];
var zoom0MarkersArr = new Array();
var zoom1MarkersArr = new Array();
var zoom2MarkersArr = new Array();
var zoom3MarkersArr = new Array();
var zoom4MarkersArr = new Array();
var zoom5MarkersArr = new Array();
for (var arrayIndex = 0; arrayIndex < markerArray.length; arrayIndex++) {
    var i = 0;
    while (i <= 5) {
        var thisMarkerTypeStr = markerArray[arrayIndex][0];        
        var thisMarkerLat = markerArray[arrayIndex][1];
        var thisMarkerLng = markerArray[arrayIndex][2];
        var thisMarkerImage = markerArray[arrayIndex][3];
        var thisMarkerImageSizeArr = markerArray[arrayIndex][i + 4];
        var thisIcon = L.icon({
            iconUrl: '../images/map/elements/' + i + '/' + thisMarkerImage + '.png',
            iconSize: thisMarkerImageSizeArr,
            className: thisMarkerImage + ' leaflet-zoom-hide'
        });
        var thisMarker = L.marker([thisMarkerLat, thisMarkerLng], {
            icon: thisIcon
        }).on("click", function () { ShowDetails(thisMarkerTypeStr); });
        window['zoom' + i + 'MarkersArr'].push(thisMarker);
        i++;
    }
}
var zoom0Markers = L.layerGroup(zoom0MarkersArr);
var zoom1Markers = L.layerGroup(zoom1MarkersArr);
var zoom2Markers = L.layerGroup(zoom2MarkersArr);
var zoom3Markers = L.layerGroup(zoom3MarkersArr);
var zoom4Markers = L.layerGroup(zoom4MarkersArr);
var zoom5Markers = L.layerGroup(zoom5MarkersArr);

函数ShowDetails当前只记录单击的元素的名称,该名称始终为train。

传递给ShowDetails函数的变量是一个本地作用域的变量,所以不确定它为什么不适合我

任何帮助/明显的建议都将不胜感激。

Javascript var变量是函数范围的,而不是块范围的。这意味着您的thisMarkerTypeStr在整个函数中是相同的。行为可以使用这个经典的setTimeout示例进行可视化:

for(var i = 0; i < 5; i++) {
  setTimeout(function() { console.log(i) }, 100);
}
// 100ms afterwards, the number 5 is printed 5 times

在不需要更改太多代码的情况下,一个可能的解决方法是在循环中创建一个闭包,该闭包捕获变量:

for(var i = 0; i < 5; i++) {
  setTimeout((function(localI) {
    return function() { console.log(localI) };
  }(i)), 100);
}

另一种(IMHO)语法上更令人愉快的方法是在循环之外创建一个maker函数:

for(var i = 0; i < 5; i++) {
  setTimeout(logMaker(i), 100);
}
function logMaker(i) {
  return function() { console.log(i); }
}

将最后一个应用于您的情况:

var thisMarker = L.marker([thisMarkerLat, thisMarkerLng], {
    icon: thisIcon
});
thisMarker.on("click", ShowDetailsMaker(thisMarkerTypeStr));
// ....
function showDetailsMaker(marker) {
    return function() {
        ShowDetails(marker);
    }
}

如果您不喜欢更经典的闭包,请尝试使用with语句:

var thisMarker = L.marker([thisMarkerLat, thisMarkerLng], {
    icon: thisIcon
});
with({
    thisMarkerTypeStr: thisMarkerTypeStr
}) {
    thisMarker.on("click", function () {
        ShowDetails(thisMarkerTypeStr);
    });
}