JaimeCheng / zxx-quiz-summary

zxx-quiz 小测收集总结
https://github.com/zhangxinxu/quiz
1 stars 0 forks source link

DOM基础测试40 - 键盘事件 #20

Open JaimeCheng opened 4 years ago

JaimeCheng commented 4 years ago

题目: dom40

原issue

回答:

// 我的回答 8分
var input = document.querySelector('#input')
var ul = document.querySelector('#list')
var list = ul.querySelectorAll('li')

// 1
list.forEach(li => {
  li.addEventListener('click', () => {
    input.value = li.innerText
    var selected = ul.querySelector('.selected')
    selected && selected.classList.remove('selected')
    li.classList.add('selected')
  })
})

// 2
document.addEventListener('keydown', e => {
  if (e.keyCode !== 38 && e.keyCode !== 40) {
    return
  }
  var selected = ul.querySelector('.selected')
  if (e.keyCode === 38) {
    if (!selected || selected === ul.firstElementChild) {
      selected && selected.classList.remove('selected')
      ul.lastElementChild.classList.add('selected')
      input.value = ul.lastElementChild.innerText
    } else {
      selected && selected.classList.remove('selected')
      selected.previousElementSibling.classList.add('selected')
      input.value = selected.previousElementSibling.innerText
    }
  }
  if (e.keyCode === 40) {
    if (!selected || selected === ul.lastElementChild) {
      selected && selected.classList.remove('selected')
      ul.firstElementChild.classList.add('selected')
      input.value = ul.firstElementChild.innerText
    } else {
      selected && selected.classList.remove('selected')
      selected.nextElementSibling.classList.add('selected')
      input.value = selected.nextElementSibling.innerText
    }
  }
})
![dom40](https://user-images.githubusercontent.com/22406024/69402456-d584d680-0d32-11ea-9da0-c6e5ed64da03.png)

优秀回答1 | [优秀回答2](https://github.com/zhangxinxu/quiz/issues/52#issuecomment-556010706

总结:

  1. li的事件绑定再ul上更合适;
  2. 程序逻辑和人类逻辑直觉;
  3. 键盘事件绑定在元素上更合适,全局可能会和浏览器上下键滚动条冲突。

> 在线demo <

JaimeCheng commented 4 years ago

zxx: 本期要点

  1. 点击事件绑定在#list列表容器上是更合适的,两点原因:1. 开销更小;2. 更健壮,不要担心里面li列表的动态变化(包括刷新更新)。
  2. 判断索引是否匹配在进行样式控制是符合人类逻辑的直觉认知的一种方式(因为现实世界重复做一件事情的成本是很高的),但是在程序代码里面并不是最好的实现。逻辑更清晰的实现:选中.selected元素并移除(不管是不是点击元素自身),点击元素在添加.selected。牺牲不值一提的执行成本,降低逻辑复杂度。意义在于,执行成本的成本是计算机的,逻辑复杂度是给人看的。最终目的都是人更轻松,计算机累一点。
  3. 键盘事件在实际开发时候,由于这种列表,都是使用keydown事件,不是keyup。
  4. 事件建议绑定在元素上,全局上下键绑定是会有问题,会和浏览器上下键微调页面滚动高度冲突。
  5. input.setAttribute('autocomplete', 'off');然后设置event.preventDefault();
  6. event.key比对event.keyCode,如果不考虑兼容IE8这样的老IE浏览器,推荐使用event.key,键盘是千奇百怪的,操作系统也是多样的,event.keyCode值会有较大出入(常规键都是一样的),使用event.key更保险一点(虽然也不是完全100%兼容),也更好记忆。