JS实现toggle功能的简单探讨
本帖最后由 马黑黑 于 2025-3-3 20:04 编辑 <br /><br /><p>JavaScript并没有toggle函数或方法,不过基于元素的classList属性带有一个toggle方法,它可以操作元素的class列表中指定的class即类,具体表现是将该类或添加到元素中来或从元素class列表中移除,从而达成基于元素class的两种模态的来回切换。试看如下的CSS+HTML代码:</p><div class="hEdiv"><pre class="hEpre">
<style>
.divbox {
margin: 20px auto;
border: 1px solid gray;
width: 400px;
height: 200px;
background: pink;
}
.bg666 { background: #666; }
</style>
<div class="divbox"></div>
</pre></div>
<p>观察上面的代码,div元素已经使用了一个class属性divbox,该属性在CSS中设计了几个基本样式,其中有粉色背景。现在我们想通过另一个class属性即CSS中的 .bg666 来改变其背景色为 #666 并且随后能够在这两种背景色之间来回切换。实现这样的功能其方法术语称作 toggle,即某种属性在两种状态之间来回切换,这和电源的开/关是同一个道理。为了展示前述基于class列表的 toggle 我们另起一组代码,用JS的 element.classList.toggle 方法给div元素加上 toggle 开关:</p>
<div class="hEdiv"><pre class="hEpre">
<style>
.mybox {
margin: 20px auto;
border: 1px solid gray;
width: 400px;
height: 200px;
background: pink;
}
.bg666 { background: #666; }
</style>
<div class="mybox" title="点击更换背景"></div>
<script>
var mybox = document.querySelector('.mybox');
mybox.onclick = () => {
mybox.classList.toggle('bg666');
//console.log(mybox.classList.value);//打印当前class列表
};
</script>
</pre></div>
<p>元素列表的 toggle 方法需要一个参数:HTML元素的class属性名称,该类属性设置由CSS预定义,对应的名称是(点+名称),这样JS就可以调用业已存在的备用CSS class类定义针对指定属性(如背景颜色或更复杂的样式)来覆盖渲染元素,并且可以和原先的指定属性所设置的渲染效果来回切换。切换的方式其实是加入或移除备用CSS class类属性,可以通过打印 classList.value 值印证。效果如下:</p>
<p class="showbox">效果</p>
<p>JS框架元老之一的JQuery封装有一个 toggle 方法,在切换元素属性或其他功能时非常方便。原生JS其实也可以做到这一点,实现方式要自己编程但并非复杂,试看如下例子:</p>
<div class="hEdiv"><pre class="hEpre">
<style>
.mybox1 {
margin: 20px auto;
border: 1px solid gray;
width: 400px;
height: 200px;
background: tan;
}
</style>
<div class="mybox1" title="点击更换背景"></div>
<script>
//自编toggle函数 :元素CSS属性值二模态切换
toggleAttrVal = (elm, attrName, val) => elm.style = elm.style === val ? '' : val;
//应用实例 :改变元素背景
var mybox1 = document.querySelector('.mybox1');
mybox1.onclick = () => toggleAttrVal(mybox1, 'background', 'teal');
</script>
</pre></div>
<p>函数 toggleAttrVal 有三个形参:elm 是元素,attrName 是CSS属性名,val 是属性值。函数通过判断指定元素 elm 的指定属性 attrName 的值是否等于传来的参数值 val,若等于,元素的属性值等于空即还原初始设置,反之令其等于 val 值。以下是运行效果:</p>
<p class="showbox">效果</p>
<p>上例只是一个简单的示例,我们从中得到的启发是,我们可以使用原生的JS实现所需的 toggle 功能。</p>
<script type="module">
import hlight from 'https://638183.freep.cn/638183/web/helight/helight1.js';
var divs = document.querySelectorAll('.hEdiv'),
pres = document.querySelectorAll('.hEpre'),
stages = document.querySelectorAll('.showbox');
var sbox = ,];
for(var j = 0; j < divs.length; j ++) {
hlight.hl(divs, pres);
if(sbox !== null) {
var idx = { stage: sbox, code: sbox };
runCodes(pres.textContent, stages);
}
}
function runCodes(str,target) {
let reg = /(<script(.*?)>)(.|\n)*?(<\/script>)/g;
let js_str, html_str;
if(str.match(reg) !== null) {
js_str = str.match(reg);
html_str = str.replace(js_str, '').trim();
js_str = js_str.replace(/<[\/]{0,1}script[^>]*>/g,'').trim();
} else {
js_str = '';
html_str = str.trim();
}
target.innerHTML = html_str;
let myfunc = new Function(js_str);
myfunc();
};
</script>
相对来说,在css里写好的,比自编toggle函数更简单些,后者的单词太长了{:4_173:} 不过这个自编的应用起来更方便,不管css里有没有,都能加出来,只要给出元素名,属性和属性值就行了{:4_187:} 感谢黑黑带来的知识,学习了{:4_199:} 这个好像只能代码设置颜色来改变背景切换,不能直接用图片吧 红影 发表于 2025-3-3 20:48
相对来说,在css里写好的,比自编toggle函数更简单些,后者的单词太长了
但是 classList 的 toggle 方法只能设置基 class列表的东东,要扩展作别的它就不行了 红影 发表于 2025-3-3 20:52
不过这个自编的应用起来更方便,不管css里有没有,都能加出来,只要给出元素名,属性和属性值就行了{:4_187 ...
他还可以改写后扩展到别的内容,不止于CSS层面的 小辣椒 发表于 2025-3-3 21:37
这个好像只能代码设置颜色来改变背景切换,不能直接用图片吧
改装一下就都可以 谢谢黑黑老师,学习了。 马黑黑 发表于 2025-3-3 23:47
但是 classList 的 toggle 方法只能设置基 class列表的东东,要扩展作别的它就不行了
是的,这个方法简单,但有局限。 马黑黑 发表于 2025-3-3 23:48
他还可以改写后扩展到别的内容,不止于CSS层面的
这个太厉害,可以加的东西更多了{:4_187:} 红影 发表于 2025-3-4 10:13
这个太厉害,可以加的东西更多了
前提是能用JS写东西 红影 发表于 2025-3-4 10:12
是的,这个方法简单,但有局限。
其实也不算简单,它需要设计配套的CSS,这个就很繁琐 梦江南 发表于 2025-3-4 10:11
谢谢黑黑老师,学习了。
{:4_190:} JS函数大人,神一样的存在。。
小白路过,问声好,溜了溜了。。。。{:4_173:} 花飞飞 发表于 2025-3-4 18:53
JS函数大人,神一样的存在。。
小白路过,问声好,溜了溜了。。。。
{:4_203:} 马黑黑 发表于 2025-3-4 19:02
其实我看了几遍的,大约知道跟开关一样切换,原理啥的就不懂了。
一烧脑就想跑。{:4_173:} 马黑黑 发表于 2025-3-3 23:48
改装一下就都可以
等黑黑的实例出来{:4_170:} 马黑黑 发表于 2025-3-4 13:02
前提是能用JS写东西
那是当然,不会写,给了机会也写不出来啊{:4_173:} 马黑黑 发表于 2025-3-4 13:03
其实也不算简单,它需要设计配套的CSS,这个就很繁琐
毕竟css离得东西容易理解啊,就觉得简单了。