写好原生JavaScript(一)

122 阅读2分钟

javascript既是面向对象的又是函数式
相信好多人都会写js,但是好的代码却不是随手写的就行。我们要从各个方面考虑
例如:要实现一个列表中,点击单个元素改变改元素的样式,可以有多种方式

<ul id="fruit">
    <li>苹果</li>
    <li>香蕉</li>
    <li>葡萄</li>
</ul>
  1. 方式1:
let fruit = document.getElementById('fruit')
let list = Array.from(fruit.querySelectorAll('li'))

list.map(x => {
    x.addEventListener('click', (e) => {
        list.map(x => {
            x.style.backgroundColor = 'white'
            x.style.color = 'black'
        })
        target.style.backgroundColor = 'black'
        target.style.color = 'white'
    })
})

这个方法固然能完成这个功能实现,而且还没有bug但是代码质量却是最烂的
先说一个缺点:给每个li都绑定了相同的事件。

  1. 方式2
#fruit li.active {
    background-color: black;
    color: white;
}
fruit.addEventListener('click', (e) => {
    e = e || window.event
    let target = e.target
    if(target.nodeName.toLowerCase() === 'li') {
        list.map(x => {
            x.className = x.className.replace(/\s?active\s?/, '')
        })
        target.className += ' active'
    }
})

方式2使用了事件代理的方式,解决了多个节点绑定同一事件的问题,js最好不要直接操作样式,那是Css应该做的

  1. 方式3
<ul id="fruit">
    <li>
        <input type="radio" id="item01" name="fruits" value="苹果" />
        <label for="item01">苹果</label>
    </li>
    <li>
        <input type="radio" id="item02"  name="fruits" value="香蕉" />
        <label for="item02">香蕉</label>
    </li>
    <li>
        <input type="radio" id="item03"  name="fruits" value="葡萄" />
        <label for="item03">葡萄</label>
    </li>
</ul>
#fruit li input{
    display: none;
}
#fruit label:hover {
    background-color: gray;
}
#fruit label {
    display: block;
}
#fruit li input:checked+label{
    background-color: black;
    color: white;
}
let fruit = document.getElementById('fruit')

fruit.addEventListener('click', (e) => {
    if(e.target.nodeName === 'INPUT') {
        let curr = fruit.querySelector('input:checked')
        console.log(curr.value)
    }
})

方式三呢,很好的对HTML,CSS和JS进行了分工,CSS处理样式,JS处理事件和数据,是一个很好的实现方式,如果想实现多选,可以直接改成多选框:

<input type="checkbox">