Javascript 在3种状态之间切换

Javascript 在3种状态之间切换,javascript,Javascript,我需要创建一个按钮,它将在3个状态之间循环。出于某种原因,这是难以置信的挑战找到。每个状态下的函数都是简单的样式更改,例如: click 1: hide div click 2: show hidden div, change bg-color click 3: reset bg-color, change font click 1: reset font, hide div 有什么想法吗?我不能使用jquery(不允许使用课堂作业) 变量状态={ 1:[{name:'display',val

我需要创建一个
按钮
,它将在3个状态之间循环。出于某种原因,这是难以置信的挑战找到。每个状态下的函数都是简单的样式更改,例如:

click 1: hide div
click 2: show hidden div, change bg-color
click 3: reset bg-color, change font
click 1: reset font, hide div
有什么想法吗?我不能使用
jquery
(不允许使用课堂作业)


变量状态={
1:[{name:'display',value:'none'}],
2:[{name:'display',value:'block'}],
3:[{name:'background color',value:'white'},{name:'prop',value:'val'}]
}
window.onload=函数(){
var mydiv=document.getElementById('mydiv');
var mybutton=document.getElementById('mybutton');
mybutton.onclick=函数(){
var num=parseInt(mydiv.getAttribute('data-state');
num=num<3?++num:1;
var nameValues=状态[num];
对于(var i=0;i
Cou可以使用一个数组,每个状态变化都有一个函数,还有一个计数器变量,循环遍历可能的状态

然后,只需通过按钮的单击处理程序调用当前状态函数

像这样的东西可以做到

var toggle = (function (el) {
    var div = document.getElementById(el); //Get the div you want to change
    var states = []; //The Array to hold the functions
    var style = {} //Will be used to save the current style
    for (var att in div.style) //Saves the style of the div *I was just lazy and did a for loop*
    style[att] = div.style[att]

    var current = 0; //The Counter

    states[0] = function () { //The first state function
        div.style["font-family"] = style["font-family"]
        div.style.display = "none";
    };
    states[1] = function () {
        div.style.display = "block";
        div.style["background-color"] = "rgb(" + [rand(), rand(), rand()] + ")"; // [1,2,3] toString is "1,2,3"
    };
    states[2] = function () {
        div.style["background-color"] = style["background-color"];
        div.style["font-family"] = "Courier New";
    }

    function rand() { //ONly to return a random number for a random bgcolor
        return ~~(Math.random() * 255)
    }
    return function () {  //The function which cycles through the states
        states[current]() //Invokes the current statechange function
        current = (current + 1) % (states.length); //Increments the counter and uses modulo to cycle
    }
})("div");

document.getElementById("click")
    .addEventListener("click", toggle);
这里有一个例子

更新: 我对它进行了一些修改,并对修改后的代码进行了注释,这应该能够更改页面上多个元素的状态

    function rand() {
        return~~ (Math.random() * 255);
    }


    var makeToggle = function (states, elements) { // I Changed it to makeToggle, The first argument accepts an array of states to cycle through, the second either an array of elements, or an array of objects with the element property (and an optional state function)
        var current = 0; //Sets the counter to zero

        for (var i = 0, ilen = elements.length; i < ilen; i++) {
            if (!elements[i].element) { //check if you passed an Object with the `element` Property
                elements[i] = {
                    element: elements[i] //If it was an array, the arrays element will be set to an object
                }; //to support arrays only
            }
            elements[i].style = {}; //to save the original style in the object
            for (var att in elements[i].element.style) {
                elements[i].style[att] = div.style[att]; // saves it
            }
        }

        function doForElements() { //Invokes either the state function passed with an element, or the general statefunction
            for (var i = 0, ilen = elements.length; i < ilen; i++) {
                var state = elements[i].states;
                if (state && typeof state[current] === "function") state = state[current];
                else state = states[current];
                state(elements[i].element, elements[i].style); //Invokes the function with the element as first parameter and the original style as second
            }

        }
        return function () { //Returns the function for the click handler
            doForElements();
            current = (current + 1) % (states.length); //cycles the current state counter
        };
    };

    var states = []; //Here the General State change functions get defined
    states[0] = function (div, style) {
        div.style["font-family"] = style["font-family"];
        div.style.display = "none";
    };
    states[1] = function (div, style) {
        div.style.display = "block";
        div.style["background-color"] = "rgb(" + [rand(), rand(), rand()] + ")";
    };
    states[2] = function (div, style) {
        div.style["background-color"] = style["background-color"];
        div.style["font-family"] = "Courier New";
    };


    var elements = [].slice.call(document.getElementsByTagName("div")); //To actually get an Array of the NodeList (all divs on the page)

    elements[4] = { //changes the 5th element (which should receive a special statechange function)
        element: elements[4],
        states: {
            1: function (div, style) { //Use an Objects property to pass an single state change instead of an array with functions
                div.style.display = "block";
                div.style["background-color"] = "yellow";
            }
        }
    };


    var toggle = makeToggle(states, elements); //sets the function for the click handler to toggle
    //Pass an Object with the Elements and an optional st

    document.getElementById("click")
        .addEventListener("click", toggle); //binds the function
函数rand(){
返回~~(Math.random()*255);
}
var makeToggle=function(states,elements){//I将其更改为makeToggle,第一个参数接受要循环的状态数组,第二个参数接受元素数组或具有element属性的对象数组(以及可选的状态函数)
var current=0;//将计数器设置为零
for(var i=0,ilen=elements.length;i

这里有一个测试

将状态保持在处理程序之外的某个地方;打开状态;做好这项工作;更新状态;您尝试过什么?请不要提倡使用
onclick=“…”
当然,隐藏的元素不应该是需要单击以取消隐藏的元素。@JanDvorak修复了答案:)最后一点:如何合并同时更改多个属性的需要?很好,+1表示巧妙:-)我还没有改变尝试这一点(明天期中考试)但你认为它能让我在一个页面上同时为每个州设置多个元素的样式吗?慢慢来=)当然可以,每个州的变化都是通过一个函数完成的,在这个函数中,你可以随意修改任意多个元素(你必须稍微修改一下)您还可以通过向数组中添加更多函数来添加更多周期,返回的函数在每次单击时循环通过所有
状态
数组函数。代码中的第一行引用e1作为父函数的参数。如果我计划设计多个元素的样式,这将如何改变?@Batman我更新了答案,如果您对代码有任何疑问,请随时提问
    function rand() {
        return~~ (Math.random() * 255);
    }


    var makeToggle = function (states, elements) { // I Changed it to makeToggle, The first argument accepts an array of states to cycle through, the second either an array of elements, or an array of objects with the element property (and an optional state function)
        var current = 0; //Sets the counter to zero

        for (var i = 0, ilen = elements.length; i < ilen; i++) {
            if (!elements[i].element) { //check if you passed an Object with the `element` Property
                elements[i] = {
                    element: elements[i] //If it was an array, the arrays element will be set to an object
                }; //to support arrays only
            }
            elements[i].style = {}; //to save the original style in the object
            for (var att in elements[i].element.style) {
                elements[i].style[att] = div.style[att]; // saves it
            }
        }

        function doForElements() { //Invokes either the state function passed with an element, or the general statefunction
            for (var i = 0, ilen = elements.length; i < ilen; i++) {
                var state = elements[i].states;
                if (state && typeof state[current] === "function") state = state[current];
                else state = states[current];
                state(elements[i].element, elements[i].style); //Invokes the function with the element as first parameter and the original style as second
            }

        }
        return function () { //Returns the function for the click handler
            doForElements();
            current = (current + 1) % (states.length); //cycles the current state counter
        };
    };

    var states = []; //Here the General State change functions get defined
    states[0] = function (div, style) {
        div.style["font-family"] = style["font-family"];
        div.style.display = "none";
    };
    states[1] = function (div, style) {
        div.style.display = "block";
        div.style["background-color"] = "rgb(" + [rand(), rand(), rand()] + ")";
    };
    states[2] = function (div, style) {
        div.style["background-color"] = style["background-color"];
        div.style["font-family"] = "Courier New";
    };


    var elements = [].slice.call(document.getElementsByTagName("div")); //To actually get an Array of the NodeList (all divs on the page)

    elements[4] = { //changes the 5th element (which should receive a special statechange function)
        element: elements[4],
        states: {
            1: function (div, style) { //Use an Objects property to pass an single state change instead of an array with functions
                div.style.display = "block";
                div.style["background-color"] = "yellow";
            }
        }
    };


    var toggle = makeToggle(states, elements); //sets the function for the click handler to toggle
    //Pass an Object with the Elements and an optional st

    document.getElementById("click")
        .addEventListener("click", toggle); //binds the function