写优雅的代码【各司其职】 | 青训营笔记

609 阅读5分钟

写优雅的代码【各司其职】 | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第五天。今天的课讲的是如何写好JavaScript
我个人认为,虽然这堂课的内容讲的是如何写好JavaScript,但是其中的思想内核却不仅仅只是写好JavaScript代码而已。鄙人以为,编程语言只是工具,编程从来不应该局限于语言的种类。如何写好写好JavaScript和如何写好C语言本质上是一样的,都是如何优雅得编写代码来让计算机为我们服务。

下面我讲这堂课上鄙人认为的重点内容记录如下,一来方便自己将来查阅,二来也希望能为读者提供微不足道的帮助。

写好JS的一些原则

image.png

本篇文字就如何让html、css和JavaScript各司其职进行简单的阐述.

我们用一段切换夜间模式的简单代码为例子来进行分析。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模式切换(白天-黑夜)-js操控版本,职能不分离</title>
    <style>
        *{
            line-height: 1.6;
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        .header{
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            align-items: center;
        }
        .content{
            width: 100%;
            min-height:100vh ;
            padding: 30px 20px;
            transition: all 1s;
        }
    </style>
</head>
<body>
    <div class="content">
        <header class="header">
            <h1>我是标题</h1>
            <label id="modeBtn" >白天</label>
        </header>
        <section>
            这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字
        </section>
    </div>

    <script>
        let modeBtn = document.querySelector("#modeBtn")
        let content = document.querySelector(".content")
        modeBtn.addEventListener('click',(e)=>{
            if(e.target.innerText === '白天'){
                content.style.color = '#FFF'
                content.style.backgroundColor = '#000'
                e.target.innerText = '夜晚'
            }else{
                content.style.color = '#000'
                content.style.backgroundColor = '#FFF'
                e.target.innerText = '白天'
            }
        })
    </script>
</body>
</html>

GIF.gif

以上代码中我们看到,简单的实现了页面白天与黑夜模式的切换,这段代码从功能上来看是ok的,没有什么大的问题。但是他有没有遵循职能分离的原则呢?

显然是没有的。上述代码中,使用JavaScript代码来设置了CSS的样式,从而达到切换页面主题的目的。但是这样的做法,使得JavaScript直接操作了样式。

换句话说,JavaScript做了额外的工作,要是JavaScript语言能给你发微信的话,我想你会收到这样一张表情包。

image.png

那么有没有不要“加钱”的做法呢?当然是有的

我们来看看接下来这段代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模式切换(白天-黑夜)-js操控版本,职能不分离</title>
    <style>
        *{
            line-height: 1.6;
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        .header{
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            align-items: center;
        }
        .content{
            width: 100%;
            min-height:100vh ;
            padding: 30px 20px;
        }
        .night{
            background-color: black;
            color: white;
        }
        body{
            transition: all 1s;
        }
    </style>
</head>
<body>
    <div class="content">
        <header class="header">
            <h1>我是标题</h1>
            <label id="modeBtn" >白天</label>
        </header>
        <section>
            这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字
        </section>
    </div>

    <script>
        let modeBtn = document.querySelector("#modeBtn")
        let content = document.querySelector(".content")
        modeBtn.addEventListener('click',(e)=>{
            let body = document.body
            if(body.className !== 'night'){
                body.className = 'night'
                e.target.innerText = '夜晚'
            }else{
                body.className = ''
                e.target.innerText = '白天'
            }
        })
    </script>
</body>
</html>

在这段代码中我们看到,具体的样式交由了css类来控制,js只负责逻辑切换的部分。这个时候JavaScript就负责了他分内的工作。这样我们就做到了职能分离。JavaScript只负责逻辑,css只负责样式。

那么,这样的做法是不是就完美了呢?或者说还有没有改进空间呢?

在这个切换白天与黑夜模式的功能中,实际上只有一个行为逻辑,就是切换css样式或者说只有一个点击事件而已。那么既然没有复杂的逻辑,可不可以不使用Javascript来实现白天与黑夜样式的切换呢?

当然是可以的。让我们来看看下面这段代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模式切换(白天-黑夜)-纯css版本</title>
    <style>
        *{
            line-height: 1.6;
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        .header{
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            align-items: center;
        }
        #myCheckbox{
            display: none;
        }
        .content{
            width: 100%;
            min-height:100vh ;
            padding: 30px 20px;
            transition: all 1s;
        }
        #myCheckbox:checked + .content{
            background-color: black;
            color: white;
            
        }
        #modeBtn::after{
            content: "白天";
        }

        #myCheckbox:checked + .content #modeBtn::after{
            content: "夜晚";
        }
    </style>
</head>
<body>
    <input type="checkbox" id="myCheckbox"/>
    <div class="content">
        <header class="header">
            <h1>我是标题</h1>
            <label id="modeBtn" for="myCheckbox"></label>
        </header>
        <section>
            这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字
        </section>
    </div>
</body>
</html>

GIF.gif

我们可以看到,上面这段代码,在没有使用Javascript的情况下,实现了白天与黑夜CSS样式的切换。这个时候有读者老爷就要问了,没有使用JavaScript,那是如何使用click事件的呢?

这里就要提到css中的伪类之一:checked了。
首先我们在页面上写一个

<input type="checkbox" id="myCheckbox"/>

我们知道,checkbox有选中与非选中两个状态。当checkox处于选中状态时,:checked这个伪类便会存在,于是我们可以利用这个特性,编写这一段css代码

 #myCheckbox:checked + .content{
    background-color: black;
    color: white;
}

这样,当checkbox被选中时,就可以设置.content类的样式,从而达到切换白天与黑夜样式的作用。 细心的读者会发现,那checkbox为什么在页面上看不到,并且为什么点击白天、黑夜文字就可以进行checkbox组件的选中与非选中状态切换呢?

下面让我们细细来看。

页面上没有显示checkbox非常简单,我们只需要设置checkbox的display属性为nono就可以了。

那么为什么点击白天、黑夜的文字也可以选中与不选择checkbox呢?

这个时候就要主要这一段代码了。首先给<input type="checkbox" id="myCheckbox"/>写上id为myCheckbox,然后将白天、黑夜文字显示的地方使用<label for="myCheckbox"></label>标签,并且写上for属性为checkbox的id。

有读者就会问了,Label标签的for属性是干嘛的呢?
这个for属性能够设置Label与哪个表单元素进行绑定。

<input type="checkbox" id="myCheckbox"/>
<div class="content">
    <header class="header">
        <h1>我是标题</h1>
        <label id="modeBtn" for="myCheckbox"></label>
    </header>
    <section>
        这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字这是一些文字
    </section>
</div>

然后通过::after伪类来设置Label标签位置显示什么文字,就完成了通过纯css进行白天-黑夜模式切换功能了。

#modeBtn::after{
    content: "白天";
}

#myCheckbox:checked + .content #modeBtn::after{
    content: "夜晚";
}