在forEach中的Javascript回调

时间:2017-08-05 19:55:02

标签: javascript arrays loops

使用Javascript:

$(document).ready(function() {
    var systems = 'https://raw.githubusercontent.com/joeberthelot88/EVE-Online-Mapper/master/eveSystems.json?token=AWUj7mQ8T_6NBaRgIcz4Xz0KQd1SazMUks5ZjpeAwA%3D%3D';

    var constellations = [20000441, 20000442, 20000443, 20000444, 20000445, 20000446, 20000447];

    var arrayX = [];
    var arrayY = [];

    $.getJSON(systems, function(data) {

        data.forEach(function(systemData) {

            // Get data and build elements for each object found in constellations array
            if(constellations.indexOf(systemData.constellation_id) > -1) {

                // Simplify location coordinates
                var x = systemData.position.x / 100000000000000;
                var y = systemData.position.y / 100000000000000;

                // Push coordinates to arrays
                arrayX.push(x);
                arrayY.push(y);

                // Get the lowest coordinate values
                var offsetX = Math.min.apply(Math, arrayX);
                var offsetY = Math.min.apply(Math, arrayY);

                // Set pixel offsets to center in the viewport
                var coordX = x + offsetX;
                var coordY = y + offsetY;

                // Build SVG elements
                var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                svg.setAttribute('id', systemData.name);
                svg.setAttribute('title', systemData.name);
                svg.setAttribute('class', 'system');
                svg.setAttribute('constellation-id', systemData.constellation_id);
                svg.setAttribute('style', 'margin-top:'+coordY+'px;margin-left:'+coordX+'px');
                svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
                document.getElementById('container').appendChild(svg);
            } else {

            }
        });       
    });

    $(this.body).panzoom();
});

这是做什么的:

  • 循环访问JSON对象
  • 对于每个对象,它会查找对象包含constellation_id
  • 的匹配项
  • 如果找到匹配项,则将坐标推送到数组,然后将每个数组中的最小数字存储为变量
  • 在每个循环中,创建一个SVG元素

问题:

在创建SVG元素期间,我使用coordXcoordY变量设置CSS边距。相反,我需要将这些变量与新的offsetXoffsetY变换掉,但这不起作用,因为offsetX和offsetY变量由于arrayX和arrayY数组而不是最终状态还在建设中。

基本上,我需要构建offsetX和offsetY变量,然后运行SVG创建。

2 个答案:

答案 0 :(得分:1)

这个迭代可以分成两个循环,第一个是构建渲染数据所需的全部,然后是svg渲染循环本身。这种分裂与在Flux / React中可以找到的渲染和状态更新的惯用分离很顺利,这可能使以后更容易切换到它们或类似的框架。

奖励积分,如果您可以避免forEach并使用没有副作用的功能。我建议使用immutable.js,因为它提供了许多有用的功能样式实用程序,并为容器(列表,地图等)提供了不可变数据结构和相等性检查(并用作键)。

此外,在旁注中,我建议您切换到letconst语法并使用箭头功能。

答案 1 :(得分:0)

您可以编写这样的函数,利用Array#filterArray#mapSet,扩展语法,箭头函数以及更多jQuery进行DOM操作:

$(function() {
    const systems = 'https://raw.githubusercontent.com/joeberthelot88/EVE-Online-Mapper/master/eveSystems.json?token=AWUj7mQ8T_6NBaRgIcz4Xz0KQd1SazMUks5ZjpeAwA%3D%3D';
    // Use a Set for faster look-up
    const constellations = new Set([20000441, 20000442, 20000443, 20000444, 20000445, 20000446, 20000447]);

    $.getJSON(systems, function(data) {
        data = data.filter(systemData => constellations.has(systemData.constellation_id));
        // Collect the coordinate values
        const arrayX = data.map(systemData => systemData.position.x / 100000000000000);
        const arrayY = data.map(systemData => systemData.position.y / 100000000000000);
        // Get least coordinate values
        const offsetX = Math.min(...arrayX);
        const offsetY = Math.min(...arrayY);
        $('#container').append( // Append array of elements in one go 
            data.map((systemData, i) => {
                // Set pixel offsets to center in the viewport
                const coordX = arrayX[i] + offsetX;
                const coordY = arrayY[i] + offsetY;
                // Build SVG elements
                const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
                return $(svg).attr({
                    id: systemData.name,
                    title: systemData.name,
                    "constellation-id": systemData.constellation_id,
                    "class": "system"
                }).css({ 
                    marginTop: coordY, 
                    marginLeft: coordX 
                });
            })
        );
    });

    $(this.body).panzoom();
});