通过重新创建已知的标签组件来增强你的开发技能,而不仅仅是瓦尼拉JavaScript和你的不可磨灭的智慧!
我们都知道他们在做什么,并在我们的网页浏览器中每天使用它们,而不给他们太多思考,然而,设计一个现代的,可重复使用的标签组件,它在移动设备上运作得很好,仅使用本地浏览器技术,实际上可能是相当具有挑战性的,并且是一个很好的机会来构建一些真实世界
的代码。
基本要求
我们的Tab组件必须是:
- 响应性
- 可重复使用
- 不稳定
- 可以设置默认标签
让我们来! 首先,我会从代码开始,然后分解正在发生的事情:
标记
以下是我们的标签组件的基本HTML标记:
1<!doctype html>
2<html lang="en">
3<head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <title>Gator tabs</title>
7 <link rel="stylesheet" href="index.css">
8</head>
9<body>
10 <div class="gator-tabs-container">
11 <ul class="gator-tabs-header">
12 <li>The nest</li>
13 <li class="default-gator-tab">Hello world!</li>
14 <li>Rise of the gator</li>
15 </ul>
16 <ul class="gator-tabs">
17 <li class="gator-tabs-container">
18 <ul class="gator-tabs-header">
19 <li>Nested 1</li>
20 <li class="default-gator-tab">Nested 2</li>
21 </ul>
22 <ul class="gator-tabs">
23 <li class="gator-tab">Some eggs in nest one</li>
24 <li class="gator-tab">Some eggs in nest two</li>
25 </ul>
26 </li>
27 <li class="gator-tab">Hello world from tab one!</li>
28 <li class="gator-tab">Believe me I know tabs, I have the best tabs. Nobody does tabs like I do.</li>
29 <li class="gator-tab">For now the eggs lay dormant but soon the gators will rise from the swamps.</li>
30 </ul>
31 </div>
32 <script src="main.js"></script>
33</body>
34</html>
风格
还有一些CSS风格,让一切看起来都很好:
1/* minimal reset */
2 * {
3 margin:0;
4 border:0;
5 padding:0;
6 box-sizing:border-box;
7 list-style:none;
8 }
9
10 body{
11 background-color: #333;
12 /* because serifs are gross (IMO) */
13 font-family: sans-serif;
14 }
15
16 .gator-tabs-container{
17 display:flex;
18 flex-direction:column;
19 width:100%;
20 }
21
22 .gator-tabs-header {
23 background-color:#DFA612;
24 display:flex;
25 flex-wrap:wrap;
26 padding:.375rem;
27 }
28
29 .gator-tabs-header > li {
30 color:#fff;
31 cursor:pointer;
32 flex-grow:1;
33 padding:.375rem;
34 font-size:1.125rem;
35 }
36
37 .gator-tabs {
38 display:flex;
39 }
40
41 .gator-tab {
42 padding:1rem;
43 color:#fff;
44 }
JavaScript 代码
现在让我们用一些简单的JavaScript来实现魔法:
1function tabify( element ){
2 const header = element.querySelector('.gator-tabs-header');
3 const content = element.querySelector('.gator-tabs');
4 const tab_headers = [...header.children];
5 const tab_contents = [...content.children];
6 tab_contents.forEach( x => x.style.display = 'none');
7 let current_tab_index = -1;
8
9 function setTab( index ){
10 if( current_tab_index > -1 ){
11 tab_headers[ current_tab_index ].style.fontWeight = 400;
12 tab_contents[ current_tab_index ].style.display = 'none';
13 }
14 tab_headers[ index ].style.fontWeight = 800;
15 tab_contents[ index ].style.display = 'flex';
16 current_tab_index = index;
17 }
18
19 default_tab_index = tab_headers.findIndex( x => {
20 return [...x.classList].indexOf('default-gator-tab') > -1;
21 });
22
23 default_tab_index = default_tab_index === -1 ? 0 : default_tab_index;
24 setTab( default_tab_index );
25 tab_headers.forEach((x,i) => x.onclick = event => setTab(i));
26}
27
28 // this is where the magic happens!
29[...document.querySelectorAll('.gator-tabs-container')]
30 .forEach(x => tabify(x));
以下是手机应用程序的屏幕截图:
重复 / 破解
我们的第一个要求是构建一些响应性的东西,这很容易通过使用 Flexbox与flex-wrap
属性解决,所以卡头现在将在移动设备上相互堆叠。
使代码可重复使用可能一开始看起来很困难,但通过将我们的代码包装成一个名为tabify
的函数,我们可以将任何东西变成一个满足所需的类 / 标签结构的标签。
最后的要求是能够在页面打开时将卡设置为默认选项,这是通过将默认-gator-tab
类添加到所需的卡头来实现的,我们的脚本将找到该类第一个卡头的索引,并使用它来设置初始卡。
在之前的一篇文章中,我们描述了使用React的构建卡(https://andsky.com/tech/tutorials/react-tabs-component),但坦率地说,我很难找到React在这种情况下具有明显的优点。
如果我们想,我们可以很容易地扩展我们所需要的内容,包括动画或更复杂的功能,但我会把这一点留给您。