一、问答题(60分)

1、JS是单线程还是多线程的语言。(2分)单线程
2、渲染页面的过程是同步还是异步执行。(2分)同步
3、列举三个常见的异步执行。(6分)setTimeout/setInterval,ajax,promise.then()
4、怎么阻止默认事件执行。(2分)

  • e.preventDefault();//阻止默认事件
  • return falsee.returnValue=false;//IE

5、怎么阻止事件冒泡。(2分)e.stopPropagation();e.cancelBubble=true;//兼容IE
6、简述事件传播机制。(6分)
在点击事件时,浏览器会首先从外往里捕获,找到点击的元素,这个阶段称为捕获阶段
捕获完后,会从里往外执行点击事件,这个阶段叫做冒泡阶段。
总的来说,捕获触发的是从外向里触发事件;冒泡触发是从里向外触发事件。
且捕获比冒泡阶段先执行。
7、什么是事件委托。(2分)

  • 通过点击子级元素来触发父级元素的事件
  • 利用事件源e.target||e.srcElment来获取点击的元素

8、DOM0级事件与DOM2级事件有什么区别。(6分)
DOM0 xx.onclick =function(){}
基于给元素的私有属性赋值,当条件达到触发私有属性方法
1.如果元素没有某个事件的私有属性,就不能基于这个方法绑定0级事件
2.只能绑定一个方法,如果多个绑定,只有最后一个绑定上
3.都是冒泡阶段触发
DOM2
xxx.addEventListener(‘click’,fn,false)
xxx.removeEventListener(‘click’,fn,false)
dispatchEvent
基于浏览器事件池机制来完成的,通过addEventListener往事件池中增加方法,removeEventListener从中移除方法
1.只要浏览器中有这个事件,都可以通过2级事件来绑定,如transitionend,DOMContentLoaded(jquery中的ready事件就是监听这个事件实现的)
2.同一个事件可以绑定多个方法,触发顺序,先绑定的先触发
3.可以人为规定在捕获或冒泡阶段触发,默认是在冒泡阶段
9、DOM2级事件如何控制事件在捕获阶段触发。(2分)第三参数传true
10、如何移除绑定的DOM2级事件。(2分)xxx.removeEventListener()
11、window.onload与$(document).ready()的区别。(4分)
1.window.onload用0级事件绑定的,只能绑定一个函数;$(document).ready()用2级事件绑定的,监听DOMContentLoaded事件实现的,可以绑定多个函数
2.$(document).ready()是页面DOM结构渲染完成执行,window.onload是页面全部渲染完才执行,比ready晚
12、什么情况会触发回流与重绘?(4分)
元素样式的改变,但宽高、大小、位置不变,如字体颜色,背景颜色等,会触发页面的重绘。
元素的宽高、大小、位置等影响页面布局改变的样式改变,会触发页面的回流。
13、如何减少回流和重绘?(4分)
1.读写分离
2.利用文档碎片统一修改元素
14、列举三个移动端常用事件。(6分)ontouchmove ontouchstart ontouchend
15、如何监听页面可视窗口发生变化。(2分)window.onresize
16、下面输出什么?(4分) 3 2 4 1

  1. function fn1(){
  2. setTimeout(()=>{
  3. console.log(1)
  4. },100)
  5. }
  6. function fn2(){
  7. console.log(2)
  8. }
  9. console.log(3);
  10. fn1();
  11. fn2();
  12. for(let i= 0;i<5;i++) {
  13. }
  14. console.log(4);

17、下面输出什么?(4分)
10 “A” NaN undefined

  1. var name = '珠峰培训';
  2. function A(x,y){
  3. var res = x + y;
  4. console.log(res,this.name);
  5. }
  6. function B(x,y){
  7. var res = x - y;//=>此时的this是函数A
  8. console.log(res,this.name);//函数的名称
  9. }
  10. B.call(A,40,30);
  11. B.call.call.call(A,20,10);

二、编程题(40分)

1、用事件委托,实现下面需求(14分)

  1. <body>
  2. <div id="box">
  3. <button data-type="+">+</button>
  4. <button data-type="-">-</button>
  5. <button data-type="*">*</button>
  6. <button data-type="/">/</button>
  7. <button data-type="%">%</button>
  8. <!-- 点击上面按钮,输出按钮的符号 -->
  9. </div>
  10. </body>
  11. <script>
  12. let box = document.getElementById('box');
  13. box.onclick = function (e) {
  14. // e.target就是点击的元素
  15. if (e.target.tagName === 'BUTTON') {
  16. let type = e.target.getAttribute('data-type');
  17. console.log(type);
  18. }
  19. };
  20. </script>

2、用requestAnimationFrame实现每次让盒子向右移动5px,移动10次(12分)
相当于执行了requestAnimationFrame 10次函数
bz4u6-5i740.gif


<style>
  #box {
    width: 100px;
    height: 100px;
    background: lightcoral;
    position: relative;
    left: 0;
  }
</style>
<body>
  <div id="box"></div>
</body>
<script>
    let box = document.querySelector('#box');
    box.onclick = function () {
        let l = 0;
        function fn() {
            requestAnimationFrame(() => {
                console.log(l);
                l += 5;
                box.style.left = l + 'px';
                if (l >= 50) {
                    return;
                }
                fn();
            });
        }
        fn();
    };
</script>

3、补全代码,实现回到页面顶部的缓动效果。(14分)
2.gif


<body>
  <button>回到顶部</button>
</body>
<script>
    let btn = document.querySelector('button');
    let h = document.documentElement.clientHeight || document.body.clientHeight;
    // 超过一屏高度,按钮才显示
    window.onscroll = function(){
      let t = document.documentElement.scrollTop;//卷曲的高度
      if(t > h){
        btn.style.display = 'block'
      }else{
        btn.style.display = 'none'
      }
    }
    btn.onclick = function(){
      // 1000ms   1000/10 = 100次
      // let t = document.documentElement.scrollTop; 距离
      // t/100 步长
      if(this.isGoing)return; //如果滚动到顶部则可以不执行下面的代码
      this.isGoing = true;//给当前元素设置自定义属性 默认为true
      let t = document.documentElement.scrollTop; //取当前页面的滚动条纵坐标位置
      let step = t/100;//1900/10 
      let timer = setInterval(() => {
        t -= step; //则每次移动1900-(1900/10)
        if(t < 0){
          t = 0;
          clearInterval(timer);
          this.isGoing = false;
        }
        document.documentElement.scrollTop = t; //赋值
      }, 10);//10ms
    }
  </script>