如何写好js

121 阅读3分钟

如何写好js| 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第2天

一、首先先知道写好js的原则:

1.各司其职:js干好自己的工作,尽量让js、css、html分离。

eg:实现一个控制网页深浅颜色模式的效果

思路1:通过if-else控制,添加一个点击事件---点击黑夜就变为黑夜模式同时按钮变为可变为白天的按钮

image.png

image.png 思路2: 首先默认的样式是白色背景黑色字体为白天,那么就可以这样思考,在点击黑夜时添加一个夜晚的样式;再点击时将夜晚是样式删掉

image.png 思路3: 实现各司其职的分离,样式就交给css,js不参与。当元素状态改变的时候,切换其样式,比如当按钮选中时改变其兄弟元素的样式

image.png

eg:实现一个控制图片放大的效果

思路1:通过点击事件,点击原图片展示放大的图片;点击关闭关掉放大的图片-----采用display控制

<html>
<head>
<meta charset="utf-8"> 
<style>
#myImg:hover {opacity: 0.7;}
.modal {
	position:relative;
    display: none;  
    overflow: auto;  
}
.modal-content {
    margin: auto;
    display: block;
	-webkit-animation: zoom 0.6s;
    animation: zoom 0.6s;
}
@-webkit-keyframes zoom {
    from {-webkit-transform: scale(0)} 
    to {-webkit-transform: scale(1)}
}
@keyframes zoom {
    from {transform: scale(0.1)} 
    to {transform: scale(1)}
}
.close {
    position: absolute;
    top: 10px;
    right: 40px;
    color: #f1f1f1;
    font-size: 20px;
    font-weight: bold;
    -webkit-animation: zoom 0.6s;
    animation: zoom 0.6s;
}
.close:hover,
.close:focus {
    color: #bbb;
    text-decoration: none;
    cursor: pointer;
}
</style>
</head>
<body>
<img id="myImg" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a5c595e6d2d24ddf8bc61dd952b68578~tplv-k3u1fbpfcp-zoom-1.image" alt="Northern Lights, Norway" width="100" height="100">
<div id="myModal" class="modal">
  <span class="close">×</span>
  <img class="modal-content" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/93ef1ce6ead44162a51ff407989aaca3~tplv-k3u1fbpfcp-zoom-1.image" id="img01" width="200" height="200">
</div>

<script>
var modal = document.getElementById('myModal');
var img = document.getElementById('myImg');
img.onclick = function(){
    modal.style.display = "block";
}
var span = document.getElementsByClassName("close")[0];
span.onclick = function() { 
    modal.style.display = "none";
}
</script>

</body>
</html>

思路2:通过CSS伪类控制,划过图片上展示,离开图片后不展示

<html>
<head>
<meta charset="utf-8"> 
<style>
#myImg:hover {opacity: 0.5;}
#myImg:hover + .modal-content{
	display :block;
	}
.modal-content {
    margin: auto;
    display: none;  
	-webkit-animation: zoom 0.6s;
    animation: zoom 0.6s;
}
@-webkit-keyframes zoom {
    from {-webkit-transform: scale(0)} 
    to {-webkit-transform: scale(1)}
}
@keyframes zoom {
    from {transform: scale(0.1)} 
    to {transform: scale(1)}
}
</style>
</head>
<body>
<img id="myImg" src="http://www.runoob.com/wp-content/uploads/2016/04/img_lights.jpg" alt="Northern Lights, Norway" width="100" height="100">
<br>
<img class="modal-content" src="http://www.runoob.com/wp-content/uploads/2016/04/img_lights.jpg" id="img01" width="200" height="200">
</body>
</html>```

### 2.组件封装:

组件具有可复用性和可扩展性的优点,组件封装后便于扩展新的功能,也便于复用组件于其他地方。<br>
#### eg:用原生js写一个轮播图
**思路1:**
用css设置绝对定位,点击第几个时展示出第几个来,默认展示第一个,其他display为none.<br>
**思路2:**
用css设置一个父元素,图片大小和该父元素相同;把所有图片放在一个元素中,作为上述父元素的孩子,overflow:hidden把多出来的大小隐藏掉;因为父元素和包含图片的元素的孩子--图片是同样大小,因此可以展示出一个完整的图片;通过原生css设置动画:animation: name 10s infinite;@keyframes name{0%{translateX(XXXpx)},50%{},100%{}};通过动画控制轮播<br>
**如果要扩展这个功能,添加无限轮播、点击轮播等,需要添加一些状态,在不改变原有代码的基础上进行扩展,复用原始的轮播,这就是组件封装与复用。**
思路:写一个插件实现轮播,当需要什么事件触发轮播的时候,事件调用传入参数,可以实现该插件的复用以及使用的解耦<br>
> 点击切换的图标需要传入当前点击的索引<br>
> 1.获取当前的轮播图片列表<br>
> 2.获取当前展示的图片<br>
> 3.切换的时候改变当前选中图片的样式,同时改变要展示图片的样式<br>

```	 class Slider{<br>
    constructor(id){
      this.container = document.getElementById(id);
      this.items = this.container
      .querySelectorAll('.slider-list__item, .slider-list__item--selected');
    }
    getSelectedItem(){
      const selected = this.container
        .querySelector('.slider-list__item--selected');
      return selected
    }
    getSelectedItemIndex(){
      return Array.from(this.items).indexOf(this.getSelectedItem());
    }
    slideTo(idx){
      const selected = this.getSelectedItem();
      if(selected){ 
        selected.className = 'slider-list__item';
      }
      const item = this.items[idx];
      if(item){
        item.className = 'slider-list__item--selected';
      }
    }
    slideNext(){
      const currentIdx = this.getSelectedItemIndex();
      const nextIdx = (currentIdx + 1) % this.items.length;
      this.slideTo(nextIdx);
    }
    slidePrevious(){
      const currentIdx = this.getSelectedItemIndex();
      const previousIdx = (this.items.length + currentIdx - 1)
        % this.items.length;
      this.slideTo(previousIdx);  
    }
  }

image.png

3.过程抽象:应用函数式编程思想

应用:节流、防抖、只执行一次的函数(执行完一次后就置为null,不再进入执行的方法中),这就是高阶函数的思想,通过闭包控制着

  • 以函数作为参数
  • 以函数作为返回值

二、实践中应用这些原则