JS+CSS:H5选项卡
本帖最后由 马黑黑 于 2022-6-15 12:56 编辑 <br /><br /><style>.wrap { margin: auto; width: fit-content; height: fit-content; display: flex; flex-direction: column; font: normal 1em / 1.4em sans-serif; }
.wrap h1 { margin: 0 auto; padding: 4px; font: 900 2em sans-serif; }
.wrap p { padding: 6px 0; }
.menu { margin: 0 0 -1px 6px; width: fit-content; height: fit-content; display: flex; gap: 4px; position: relative; }
.item { width: 60px; height: 30px; background: #fff; border: 1px solid; border-bottom: none; font: normal 14px / 30px sans-serif; color: black; text-align: center; cursor: pointer; }
.noborder { border: none; background: none; }
.contents { width: 600px; min-height: 400px; border: 1px solid; background: #fff; box-shadow: 0 2px 10px #000; padding: 10px; }
.conts { width: 100%; height: 100%; }
.noconts { display: none; }
.conts pre { font-size: 14px; }
</style>
<div class="wrap">
<h1>h5选项卡</h1>
<div class="menu">
<div class="item">简介</div>
<div class="item noborder">CSS代码</div>
<div class="item noborder">JS代码</div>
</div>
<div class="contents">
<div class="conts">
<p>HTML没有原生的选项卡,而选项卡是web的刚需,因此需要自己制作。选项卡其实就是多标签,在同一页内可以自由切换,增大信息量的同时方便浏览。实现方式主要是以下这两种:纯CSS、CSS+JS。</p>
<p>本例为原创h5选项卡,使用JS+CSS实现,内部结构由div构造。未做过兼容性测试,不过即使存在兼容性问题,理论上它依然可以正常运行,仅是好看与否而已。</p>
<pre>附一:HTML结构
<<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"wrap"</span>>
<<span style='color:darkred'>h</span>1>h5选项卡</h1>
<<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"menu"</span>>
<<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"item"</span>>项目一<<span style='color: darkred'>/div</span>>
<<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"item noborder"</span>>项目二<<span style='color: darkred'>/div</span>>
<<span style='color: darkred'>/div</span>>
<<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"contents"</span>>
<<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"conts"</span>>内容一<<span style='color: darkred'>/div</span>>
<<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"conts noconts"</span>>内容二<<span style='color: darkred'>/div</span>>
<<span style='color: darkred'>/div</span>>
<<span style='color: darkred'>/div</span>>
</pre>
<p>使用时,需要增设项目和内容的,按“项目二”和“内容二”的格式分别在其下复制相同代码即可,项目与内容量需保持一致,内容与菜单需保持对应关系。</p>
</div>
<div class="conts noconts">
<p>附二:CSS代码<br></p>
<p><span style='color: red;'>.wrap </span>{ <span style='color: blue;'>margin</span>: auto; <span style='color: blue;'>width</span>: fit-content; <span style='color: blue;'>height</span>: fit-content; <span style='color: blue;'>display</span>: flex; <span style='color: blue;'>flex-direction</span>: column; <span style='color: blue;'>font</span>: normal 1em / 1.4em sans-serif; }<br>
<span style='color: red;'>.wrap h1 </span>{ <span style='color: blue;'>margin</span>: 0 auto; <span style='color: blue;'>padding</span>: 4px; <span style='color: blue;'>font</span>: 900 2em sans-serif; }<br>
<span style='color: red;'>.menu </span>{ <span style='color: blue;'>margin</span>: 0 0 -1px 6px; <span style='color: blue;'>width</span>: fit-content; <span style='color: blue;'>height</span>: fit-content; <span style='color: blue;'>display</span>: flex; <span style='color: blue;'>gap</span>: 4px; <span style='color: blue;'>position</span>: relative; }<br>
<span style='color: red;'>.item </span>{ <span style='color: blue;'>width</span>: 60px; <span style='color: blue;'>height</span>: 30px; <span style='color: blue;'>background</span>: #fff; <span style='color: blue;'>border</span>: 1px solid; <span style='color: blue;'>border-bottom</span>: none; <span style='color: blue;'>font</span>: normal 14px / 30px sans-serif; <span style='color: blue;'>color</span>: black; <span style='color: blue;'>text-align</span>: center; <span style='color: blue;'>cursor</span>: pointer; }<br>
<span style='color: red;'>.noborder </span>{ <span style='color: blue;'>border</span>: none; <span style='color: blue;'>background</span>: none; }<br>
<span style='color: red;'>.contents </span>{ <span style='color: blue;'>width</span>: 600px; <span style='color: blue;'>height</span>: 420px; <span style='color: blue;'>border</span>: 1px solid; <span style='color: blue;'>background</span>: #fff; <span style='color: blue;'>box-shadow</span>: 0 2px 10px #000; <span style='color: blue;'>padding</span>: 10px; }<br>
<span style='color: red;'>.conts </span>{ <span style='color: blue;'>width</span>: 100%; <span style='color: blue;'>height</span>: 100%; }<br>
<span style='color: red;'>.noconts </span>{ <span style='color: blue;'>display</span>: none; }
</p>
<p>【注】 项目名称偏长时请修改 .item 的 width 值。</p>
</div>
<div class="conts noconts">
<p>附三:JS代码<br></p>
<pre><span style='color: blue'>let</span> items = <span style='color: red'>document</span>.querySelectorAll(<span style='color: magenta'>'.item'</span>),
conts = <span style='color: red'>document</span>.querySelectorAll(<span style='color: magenta'>'.conts'</span>);
<span style='color: blue'>let</span> currentKey = 0;
<span style='color: red'>Array</span>.from(items).forEach((item,key) => {
item.onclick = () => {
currentKey = key;
setTab();
}
})
<span style='color: blue'>let</span> setTab = () => {
<span style='color: red'>Array</span>.from(items).forEach((item,key) => {
item.className = key == currentKey ? <span style='color: magenta'>'item'</span> : <span style='color: magenta'>'item noborder'</span>;
conts.style.display = key == currentKey ? <span style='color: magenta'>'block'</span> : <span style='color: magenta'>'none'</span>;
})
}
</pre>
<p>【注】 封装好的JS代码功能为选项卡切换,它能自动识别HTML中的项目与内容。</p>
</div>
</div>
</div>
<script>
let items = document.querySelectorAll('.item'), conts = document.querySelectorAll('.conts');
let currentKey = 0;
Array.from(items).forEach((item,key) => {
item.onclick = () => {
currentKey = key;
setTab();
}
})
let setTab = () => {
Array.from(items).forEach((item,key) => {
item.className = key == currentKey ? 'item' : 'item noborder';
conts.style.display = key == currentKey ? 'block' : 'none';
})
}
</script>
为方便复制,再给出范例的完整代码:
<style>
.wrap { margin: auto; width: fit-content; height: fit-content; display: flex; flex-direction: column; font: normal 1em / 1.4em sans-serif; }
.wrap h1 { margin: 0 auto; padding: 4px; font: 900 2em sans-serif; }
.menu { margin: 0 0 -1px 6px; width: fit-content; height: fit-content; display: flex; gap: 4px; position: relative; }
.item { width: 60px; height: 30px; background: #fff; border: 1px solid; border-bottom: none; font: normal 14px / 30px sans-serif; color: black; text-align: center; cursor: pointer; }
.noborder { border: none; background: none; }
.contents { width: 600px; height: 420px; border: 1px solid; background: #fff; box-shadow: 0 2px 10px #000; padding: 10px; }
.conts { width: 100%; height: 100%; }
.noconts { display: none; }
</style>
<div class="wrap">
<h1>h5选项卡</h1>
<div class="menu">
<div class="item">项目一</div>
<div class="item noborder">项目二</div>
</div>
<div class="contents">
<div class="conts">内容一</div>
<div class="conts noconts">内容二</div>
</div>
</div>
<script>
let items = document.querySelectorAll('.item'), conts = document.querySelectorAll('.conts');
let currentKey = 0;
Array.from(items).forEach((item,key) => {
item.onclick = () => {
currentKey = key;
setTab();
}
})
let setTab = () => {
Array.from(items).forEach((item,key) => {
item.className = key == currentKey ? 'item' : 'item noborder';
conts.style.display = key == currentKey ? 'block' : 'none';
})
}
</script>
论坛中使用,使用给 p 标签设置一下样式,否段落之间的文本间隔太小:
.wrap p { padding: 6px 0; } 回家再来研究。 这个选项卡好,不用来回翻页了,可以通过点开选项看到所有内容{:4_187:} 好像昨天的那种加点时间间隔的更好看{:4_187:} 也就是menu只管标题,contents只管内容吧? 去看了一眼,昨天那个还是纯CSS的呢。 不知道又是啥高级马术{:4_203:} 樵歌 发表于 2022-6-15 17:08
不知道又是啥高级马术
这个是常用到的技术,论坛就用上的 红影 发表于 2022-6-15 16:50
去看了一眼,昨天那个还是纯CSS的呢。
纯CSS我要重新做一个,也是照本例的样式去做,晚饭后可以做好 红影 发表于 2022-6-15 16:47
也就是menu只管标题,contents只管内容吧?
是这样的分工 红影 发表于 2022-6-15 16:42
这个选项卡好,不用来回翻页了,可以通过点开选项看到所有内容
选项卡在编程当中都会用上,web页也不例外。但很遗憾,HTML5真的没有选项卡。 红影 发表于 2022-6-15 16:43
好像昨天的那种加点时间间隔的更好看
这个容易的,就是加一个 @keyframes 动画 马黑黑 发表于 2022-6-15 18:24
纯CSS我要重新做一个,也是照本例的样式去做,晚饭后可以做好
看到了,虽然不是很懂,但效果不错。 马黑黑 发表于 2022-6-15 18:25
选项卡在编程当中都会用上,web页也不例外。但很遗憾,HTML5真的没有选项卡。
黑黑对各种需求都研究得很透呢{:4_187:} 马黑黑 发表于 2022-6-15 18:26
这个容易的,就是加一个 @keyframes 动画
加个动画感觉更好呢{:4_187:} 再来好好学习、天天向上! 红影 发表于 2022-6-15 20:57
加个动画感觉更好呢
花俏的东西很多时候还是需要的 红影 发表于 2022-6-15 20:56
黑黑对各种需求都研究得很透呢
一般,偶尔用到什么的时候,就配套去做做