我如何使这个JavaScript更短/更好没有框架

How do I make this JavaScript shorter/better without frameworks?

本文关键字:更好 框架 更短 何使这 JavaScript      更新时间:2023-09-26
function prepareEventHandlers() {
    var sectionButton1 = document.getElementById("sectionButton1");
    var sectionButton2 = document.getElementById("sectionButton2");
    var sectionButton3 = document.getElementById("sectionButton3");
    var sectionButton4 = document.getElementById("sectionButton4");
    var sectionButton5 = document.getElementById("sectionButton5");
    var enabled1 = true;
    var enabled2 = false;
    var enabled3 = false;
    var enabled4 = false;
    var enabled5 = false;

    function checkEnabled() {
        if (enabled1) {
            sectionButton1.setAttribute("class", "sectionButtonEnabled");
        }
        if (enabled2) {
            sectionButton2.setAttribute("class", "sectionButtonEnabled");
        }
        if (enabled3) {
            sectionButton3.setAttribute("class", "sectionButtonEnabled");
        }
        if (enabled4) {
            sectionButton4.setAttribute("class", "sectionButtonEnabled");
        }
        if (enabled5) {
            sectionButton5.setAttribute("class", "sectionButtonEnabled");
        }
    }
    checkEnabled();
    sectionButton1.onmouseover = function() {
        if (enabled1) {
            sectionButton1.setAttribute("class", "sectionButtonOver");
        }
    };
    sectionButton1.onmouseout = function() {
        if (enabled1) {
            sectionButton1.setAttribute("class", "sectionButtonEnabled");
        }
    };
    sectionButton2.onmouseover = function() {
        if (enabled2) {
            sectionButton2.setAttribute("class", "sectionButtonOver");
        }
    };
    sectionButton2.onmouseout = function() {
        if (enabled2) {
            sectionButton2.setAttribute("class", "sectionButtonEnabled");
        }
    };
    sectionButton3.onmouseover = function() {
        if (enabled3) {
            sectionButton3.setAttribute("class", "sectionButtonOver");
        }
    };
    sectionButton3.onmouseout = function() {
        if (enabled3) {
            sectionButton3.setAttribute("class", "sectionButtonEnabled");
        }
    };
    sectionButton4.onmouseover = function() {
        if (enabled4) {
            sectionButton4.setAttribute("class", "sectionButtonOver");
        }
    };
    sectionButton4.onmouseout = function() {
        if (enabled4) {
            sectionButton4.setAttribute("class", "sectionButtonEnabled");
        }
    };
    sectionButton5.onmouseover = function() {
        if (enabled5) {
            sectionButton5.setAttribute("class", "sectionButtonOver");
        }
    };
    sectionButton5.onmouseout = function() {
        if (enabled5) {
            sectionButton5.setAttribute("class", "sectionButtonEnabled");
        }
    };
}

window.onload = function() {
    prepareEventHandlers();
};

每当您发现自己编写变量名如"foo1", "foo2"等,并且它们都或多或少地做相同的事情时,您真的需要停下来,备份并声明一个数组。

function prepareEventHandlers() {
    var sectionButtons = [];
    for (var i = 1; i <= 5; ++i)
      sectionButtons[i] = document.getElementById('sectionButton' + i);
    var enabled = [ true, false, false, false, false ];
    function checkEnabled() {
        for (var i = 1; i <= 5; ++i)
          if (enabled[i]) sectionButtons[i].className = 'sectionButtonEnabled';
    }
    checkEnabled();
    for (i = 1; i <= 5; ++i) {
      sectionButton[i].onmouseover = function(i) {
        return function() {
          if (enabled[i]) sectionButton[i].className = 'sectionButtonOver');
        }
      }(i);
      sectionButton[i].onmouseout = function(i) {
        return function() {
          if (enabled[i]) sectionButton[i].className = 'sectionButtonEnabled';
      }(i);
    }
}

window.onload = function() {
    prepareEventHandlers();
};

现在,还有两件事:

  1. 不要用setAttribute()来设置class属性。相反,操作DOM元素的"className"属性。
  2. 与其将类直接设置为这些字符串,不如构造自己的"addClass()"answers"removeClass()"函数。请记住,类可以是类名的列表,用空格分隔。这样的函数看起来像这样:

    function addClass(elem, c) {
      elem.className += ' ' + c;
    }
    function removeClass(elem, c) {
      elem.className = elem.className.replace(new RegExp('''b' + c + '''b', 'g'), ''));
    }
    

EDIT

我同意很多关于在数组中存储数据的其他答案,但不是并行数组,我会使用一个对象数组:

var i, buttonData = [];
for(i = 1; i <= 5; i++)
   buttonData.push({ "enabled" : false, 
                     "button": document.getElementById("sectionButton" + i) });
buttonData[0].enabled = true;

然后:

for (i = 0; i < buttonData.length; i++) {
     setClassIfEnabled(buttonData[i].enabled, buttonData[i].button)
}

或者如果你想保持简单,下面的原始答案仍然会从原始版本中删除大量代码:


使用helper方法重构重复的代码

function setClassIfEnabled(enabled, button){
    if (enabled) {
          button.setAttribute("class", "sectionButtonEnabled");
    }
}

function checkEnabled() {
     setClassIfEnabled(enabled1, sectionButton1);
     setClassIfEnabled(enabled2, sectionButton2);
     setClassIfEnabled(enabled3, sectionButton3);
     setClassIfEnabled(enabled4, sectionButton4);
     setClassIfEnabled(enabled5, sectionButton5);
}

function setMouseOverIfEnabled(enabled, button) {
    button.onmouseover = function() {
        if (enabled) {
            button.setAttribute("class", "sectionButtonEnabled");
        }
    };
}
setMouseOverIfEnabled(enabled1, sectionButton1);
setMouseOverIfEnabled(enabled2, sectionButton2);
setMouseOverIfEnabled(enabled3, sectionButton3);
setMouseOverIfEnabled(enabled4, sectionButton4);
setMouseOverIfEnabled(enabled5, sectionButton5);

当然对mouseout

做同样的事情

另外,你可能想要考虑使用addEventListener来添加你的事件

function setMouseOverIfEnabled(enabled, button) {
    button.addEventListener("mouseover", function() {
        if (enabled) {
            button.setAttribute("class", "sectionButtonEnabled");
        }
    });
}

首先:使用onmouseover和onmouseout样式按钮是90年代的东西。你现在可以对CSS做同样的事情。

.sectionButtonEnabled       { regular styles here }
.sectionButtonEnabled:hover { mouseover styles here }

(注意,对于IE,这需要"标准模式"——read: have a doctype line——以及IE7或更高版本)

现在,如果你真的想用旧的、过时的方式做事……

function prepareEventHandlers() {
    var buttons = [
        "sectionButton1",
        "sectionButton2",
        "sectionButton3",
        "sectionButton4",
        "sectionButton5"
    ];
    var enabled = [ true, false, false, false, false ];
    for (var i = 0; i < buttons.length; ++i) {
        var elem = document.getElementById(buttons[i]);
        if (enabled[i]) {
            elem.className   = "sectionButtonEnabled";
            // Since you're only attaching the event handler to enabled buttons,
            // you already know that `enabled` is true. So you don't even need to
            // check, since there's no way to change your local variable.
            elem.onmouseover = function() {
                this.className="sectionButtonOver";
            };
            elem.onmouseout  = function() {
                this.className="sectionButtonEnabled";
            };
        }
    }
}

如果你不需要鼠标悬停处理程序,你可以去掉它们,只使用上面提到的CSS。

以下是浓缩版。您绝对不希望只使用不同的变量重复代码块。要么使用循环,要么创建一个局部函数。在本例中,由于您的id是顺序的,因此循环在这里工作得很好:

function prepareEventHandlers()
{
    var button;
    var enabled = [true, false, false, false, false];
    for (var i = 0; i < enabled.length; i++) {
        button = document.getElementById("sectionButton" + (i + 1));
        button.buttonEnabled = enabled[i];
        if (button.buttonEnabled) {
           button.className = "sectionButtonEnabled";
        }
        button.onmouseover = function() {
            if (this.buttonEnabled) {
                this.className = "sectionButtonOver";
            }
        }
        button.onmouseout = function() {
            if (this.buttonEnabled) {
                this.className = "sectionButtonEnabled";
            }
        }
    }
}

此代码还允许您稍后在其他代码中通过操作按钮的buttonEnabled属性和/或className来启用按钮,事件处理程序将自动执行正确的操作。