在3个状态之间切换
Toggle that cycles through 3 states
我需要创建一个button
,它将在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
(类分配,不允许)
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);
以下是JSFiddle 的一个示例
更新:
我对它进行了一些修改,并对更改后的代码进行了注释,这应该能够更改页面上多个元素的状态
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
这里有一个JSBin来试用
<div id="mydiv" data-state="0"></div>
<input type="button" id="mybutton" value="Change State" />
var states = {
1: [{ name: 'display', value: 'none'}],
2: [{ name: 'display', value: 'block'}],
3: [{ name: 'background-color', value: 'white'}, { name: 'prop', value: 'val' }]
}
window.onload = function(){
var mydiv = document.getElementById('mydiv');
var mybutton = document.getElementById('mybutton');
mybutton.onclick = function (){
var num = parseInt(mydiv.getAttribute('data-state'));
num = num < 3 ? ++num : 1;
var nameValues = states[num];
for(var i = 0; i < nameValues.length; i++)
mydiv.style[nameValues[i].name] = nameValues[i].value;
}
}
相关文章:
- 在Knockoutjs中的ViewModels之间共享变量状态
- 设置两个反应组件之间状态的正确方式
- new Datamap() 在调用之间保持内存的共享状态
- 在aspx页面c#之间传递/引用/发送变量/会话状态
- angular ui路由器卡在两个状态之间
- 在角度上不同控制器之间共享状态
- 两个类之间的状态
- UI 路由器 - 在状态之间转换时记住滚动位置
- 在 React/Redux 中管理同级组件之间的滚动状态
- 在状态之间传递对象
- JavaScript-使用sessionStorage保存文档之间共享的复选框状态
- 小黄瓜-在场景之间保持状态
- Ember JS中控制器之间共享状态的正确方式
- 如何在 CSS3 中的动画之间保持状态
- 使秒表在请求之间处于活动状态
- 在两个组件之间传输状态
- 如何使用 Angular JS 在状态之间导航
- 在两个或多个 UL 列表之间切换,如果单击一个列表,则其他列表会自动以初始状态返回,就像从未单击过一样
- 离子 - 在状态之间移动时,页面内容位于屏幕外部
- 如何在路由更改之间维护视图(控制器)状态