代码之家  ›  专栏  ›  技术社区  ›  Taras RAno

如何使按钮执行相同的代码,但相应地使用不同的变量?

  •  1
  • Taras RAno  · 技术社区  · 7 年前

    亲爱的大家。拜托,不要对我太苛刻,我是新来的 JavaScript OpenLayers公司 .

    我正在应用相同的操作 点击 多个按钮的功能,这些按钮实际执行相同的任务,但值不同。

    我在HTML部分有六个按钮:

    <button id="pan-to-kiev">Kiev</button>
    <button id="pan-to-munich">Munich</button>
    <button id="pan-to-vienna">Vienna</button>
    <button id="pan-to-dresden">Dresden</button>
    <button id="pan-to-enschede">Enschede</button>
    <button id="pan-to-bonn">Bonn</button>

    我还有放置在JS表中的对象:

    var cities = [
      {name: "Kiev", lonlat: [30.523400, 50.450100], color: '#006699', id:"pan-to-kiev"},
      {name: "Munich", lonlat: [11.581980, 48.135125], color: '#AB4450', id:"pan-to-munich"},
      {name: "Vienna", lonlat: [16.373819, 48.208174], color: '#93648D', id:"pan-to-vienna"},
      {name: "Dresden", lonlat: [13.737262, 51.050409], color: '#FFC65D', id:"pan-to-dresden"},
      {name: "Enschede", lonlat: [6.893662, 52.221537], color: '#F16745', id:"pan-to-enschede"},
      {name: "Bonn", lonlat: [7.0954900, 50.7343800], color: '#4CC3D9', id:"pan-to-bonn"}
    ];

    这是我写的一段代码,它是可执行的,但我知道这是胡说八道,因为我的代码必须更加明确和简短,因为有些变量会重复。

    function onClick(id, callback) {
      document.getElementById(id).addEventListener('click', callback);
    }
    
    onClick(cities[0]["id"], function() {
        view.animate({
          center: ol.proj.fromLonLat(cities[0]["lonlat"]),
          duration: 1500
        });
      });
    
    onClick(cities[1]["id"], function() {
        view.animate({
          center: ol.proj.fromLonLat(cities[1]["lonlat"]),
          duration: 1500
        });
      });
    
    onClick(cities[2]["id"], function() {
      view.animate({
        center: ol.proj.fromLonLat(cities[2]["lonlat"]),
        duration: 1500
      });
    });
    
    onClick(cities[3]["id"], function() {
      view.animate({
        center: ol.proj.fromLonLat(cities[3]["lonlat"]),
        duration: 1500
      });
    });
    
    onClick(cities[4]["id"], function() {
      view.animate({
        center: ol.proj.fromLonLat(cities[4]["lonlat"]),
        duration: 1500
      });
    });
    
    onClick(cities[5]["id"], function() {
      view.animate({
        center: ol.proj.fromLonLat(cities[5]["lonlat"]),
        duration: 1500
      });
    });

    我的想法行不通

     for (var city in cities) {
       onClick(cities[city]["id"], function() {
         view.animate({
           center: ol.proj.fromLonLat(cities[city]["lonlat"]),
           duration: 1500
         });
       });
       console.log(cities[city]["id"]);
    }

    你能这么好心地帮助我吗,或者至少向我解释一下,为了能够用for循环获得更好的代码,我应该在这里更改什么?

    非常感谢各位专家。

    2 回复  |  直到 7 年前
        1
  •  1
  •   5ar    7 年前

    在里面 for (var city in cities) 城市 已经是一个对象,使用 城市 在循环中,只需使用您拥有的对象。

    但是,在迭代数组时,应该使用 for...of 甚至更好 forEach() ,如中所示 the MDN documentation for for...in .

    这是 forEach公司 使用lambdas实现相同的循环,以避免 this :

    cities.forEach(city => { 
      onClick(city.id, () => {
        view.animate({
          center: ol.proj.fromLonLat(city["lonlat"]),
          duration: 1500
        });
      });
      console.log(city.id); 
    });
    
        2
  •  1
  •   Juorder Gonzalez    7 年前

    你的代码符合你的目的,唯一的问题是你在for循环中失去了上下文,所以你需要做一个函数闭包来避免这种行为,所以你只需要更改代码的这一部分就可以了。

    for (var city in cities) {
       onClick(city.id, function(cityPassed){
         return function() {
           view.animate({
             center: ol.proj.fromLonLat(cityPassed["lonlat"]),
             duration: 1500
           });
         }
       // pass the city variable
       }(city));
    }
    

    正如5ar所说,您不需要访问 cities[city]["lonlat"] 又是因为 city 已经是数组中的对象,因此您只需要使用它,请在此处检查上面的Javascript闭包: https://developer.mozilla.org/es/docs/Web/JavaScript/Closures

    我希望它能帮助你。