【问题标题】:Code Advice - How to make more concise (Javascript/Jquery)代码建议 - 如何更简洁 (Javascript/Jquery)
【发布时间】:2011-03-28 21:12:12
【问题描述】:

我正在努力使我的代码更简洁(即,更少重复的代码)。我从我的主管那里得到了一些关于如何使我最近的代码更简洁的建议,但我不确定如何去做。

我有一些坐标用于检查用户是否在 div 的某个区域内单击。有人告诉我,我应该将所有坐标放在一个数组中,并在需要时“循环”以获取它们。我 - 想 - 我理解他的建议,但我不能完全理解它,因为我仍然缺乏编程经验。以下是我到目前为止所做的工作,以便您更好地了解正在发生的事情:

    $("#div1").click(function(e)
    {
        // Arrays containing the x and y values of the rectangular area around a farm
        // [minX, maxX, minY, maxY]
        var div1_Coord_Area1= [565, 747, 310, 423];
        var div1_Coord_Area2= [755, 947, 601, 715];

        if(areaX >= Reg2_Coord_Farm1[0] && areaX <= Reg2_Coord_Farm1[1] && areaY >= Reg2_Coord_Farm1[2] && areaY <= Reg2_Coord_Farm1[3]) 
        {
            alert("You clicked in the first area");
        }
        if(areaX >= Reg2_Coord_Farm2[0] && areaX <= Reg2_Coord_Farm2[1] && areaY >= Reg2_Coord_Farm2[2] && areaY <= Reg2_Coord_Farm2[3]) 
        {
            alert("You clicked in the second area");
        } 
});

不用担心我是如何计算的;我把那段代码从方法中去掉了,因为它基本上是不相关的,但如果你想知道的话,它就在那里。

我为每组坐标创建了一个数组,然后简单地调用它们。然而,这并不是“循环”一个充满每个区域所有坐标的巨型阵列。你能想出一种方法来做到这一点,还是我目前能做的最好的?

【问题讨论】:

    标签: javascript jquery arrays mouseclick-event


    【解决方案1】:

    我认为他的意思更像是这样的:

    $("#div1").click(function(e){
        // Arrays containing the x and y values of the rectangular area around a farm
        // For each array: [area1, area2, area3, ... areaX]
        var minX = [565, 755];
        var maxX = [747, 947];
        var minY = [310, 601];
        var maxY = [423, 715];
    
        for (var i = 0; i < minX.length; i++) {
          if (areaX >= minX[i] && areaX <= maxX[i] && areaY >= minY[i] && areaY <= maxY[i]) {
            alert("You clicked in area " + (i+1));
          }
        }
    });
    

    这样,您可以检查更多区域,但不必更改循环,因为它将始终遍历数组中的所有项目,无论是上面的 2 个、10 个还是 100 个。

    【讨论】:

    • 这看起来也不错。我会研究这两个建议,看看哪一个最适合我。
    • 这个答案对我来说效果最好;它使我的代码更加简洁,而且我认为它完成了我的主管想要它做的事情。非常感谢!
    【解决方案2】:

    您可以快速浏览一下,将点击区域提取到一个单独的函数中。

    类似的东西。

    $("#div1").click(function(e)
    {
        // Arrays containing the x and y values of the rectangular area around a farm
        // [minX, maxX, minY, maxY]
        var div1_Coord_Area1= [565, 747, 310, 423];
        var div1_Coord_Area2= [755, 947, 601, 715];
    
        if(inArea(div1_Coord_Area1, someStructForMouseLocation)) 
        {
            alert("You clicked in the first area");
        }
        if(inArea(div1_Coord_Area2, someStructForMouseLocation)) 
        {
            alert("You clicked in the second area");
        } 
    });
    
    function inArea(coordArea, mouseLocation)
    {
        return mouseLocation.X >= coordArea[0] && mouseLocation.X <= coordArea[1] && mouseLocation.Y >= coordArea[2] && mouseLocation.Y <= coordArea[3]
    }
    

    var div1_Coord_Area1= [565, 747, 310, 423]; 和 var div1_Coord_Area2= [755, 947, 601, 715]; 中似乎还有一些“神奇”数字,我会考虑将它们设为全局变量,这样它们就超出了 click 函数的范围。

    应该是这样的

    // Arrays containing the x and y values of the rectangular area around a farm
    // [minX, maxX, minY, maxY]
    var div1_Coord_Area1= [565, 747, 310, 423];
    var div1_Coord_Area2= [755, 947, 601, 715];
    
    $("#div1").click(function(e)
    {
        if(inArea(div1_Coord_Area1, someStructForMouseLocation)) 
        {
            alert("You clicked in the first area");
        }
        if(inArea(div1_Coord_Area2, someStructForMouseLocation)) 
        {
            alert("You clicked in the second area");
        } 
    });
    
    function inArea(coordArea, mouseLocation)
    {
        return mouseLocation.X >= coordArea[0] && mouseLocation.X <= coordArea[1] && mouseLocation.Y >= coordArea[2] && mouseLocation.Y <= coordArea[3]
    }
    

    希望您能看到我的流程是进一步完善的流程之一。不要期望在您第一次创建方法时编写干净的代码。你必须事后看它,看看它是否会讲故事。另一个变化是div1_Coord_Area1 的名称,这个名称是否真的体现了变量的意图?不。HotSpotArea1 是否意味着更多?请记住,您是在用代码讲故事。这样做的次数越多,下一个人使用最少的大脑周期来阅读代码就越好。

    您必须不断改进才能获得真正干净的代码。

    【讨论】:

    • 这可能有效。我会看看它是如何在我的代码中实现的,然后告诉你我发现了什么。
    • 我很欣赏额外的建议和代码。我会说我的名字叫div1_Coord_Area1,因为我有不止 1 个 div 和每个里面的更多区域。
    【解决方案3】:

    如果我是你,我会让你的区域成为对象:

    // think of this as your ClickArea class
    function ClickArea(minX, maxX, minY, maxY, description) {
        this.minX = minX;
        this.maxX = maxX;
        this.minY = minY;
        this.maxY = maxY;
        this.description = description;
    };
    ClickArea.prototype.isInside = function(areaX, areaY) {
        return (areaX >= this.minX && areaX <= this.maxX && areaY >= this.minY && areaY <= this.maxY);
    };
    

    现在,您可以像这样创建 ClickArea 对象:

    var area = new ClickArea(565, 747, 310, 423, "Area 1");
    

    但是你会希望它们在一个数组中,所以我建议像这样创建它们:

    var areas = [
        new ClickArea(565, 747, 310, 423, "Area 1"),
        new ClickArea(365, 745, 330, 423, "Area 2")
    ];
    // you can also add new ClickAreas using the array's push method:
    areas.push(new ClickArea(333, 444, 555, 566, "Area 3"));
    

    然后您可以使用 for 循环遍历它们:

    for(var i = 0; i < areas.length; i++) {
        if(areas[i].isInside(areaX, areaY)) {
            alert("You clicked in " + areas[i].description);
        }
    }
    

    【讨论】:

    • 感谢您的建议,但我现在没有时间完全重做代码。不过我会保留这个以供将来参考。
    • 我明白了。最终,这将提供更大的灵活性,因为您可以向对象添加更多方法——reposition()、scale() 等...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    相关资源
    最近更新 更多