常见的面试题,最简单的话,到处最深处的含义

136 阅读5分钟

什么是 dom?

1 DOM 是 W3C(万维网联盟)的标准 定义了访问 HTML 和 XML 文档的标准

 

dom 节点的 Attribute 和 Property 有何区别?

什么是 Property

每个 DOM 节点都是一个对象,有自己的 property 和 method

什么是 Attribute

出现在dom中,js提供了getAttribute/setAttribute 等方法来设置和获取自定义属性值

 

dom 结构操作怎样添加、移除、移动、复制、创建和查找节点?

1、 创建新节点****

****createDocumentFragment() //创建一个 DOM 片段

createElement() //创建一个具体的元素

createTextnode() //创建一个文本节点

2、添加、移除、替换、插入

appendChild()

removeChild()

replaceChild()

insertBefore() //并没有

3、查找

getElementsByTagName() //通过标签名称

getElementsByName() //通过元素的 Name 属性的值(IE 容错能力较强,

会得到一个数组,其中包括 id 等于 name 值的)

getElementById() //通过元素 Id,唯一性

 

 

dom 事件模型?

DOM 事件模型分为两种:事件捕获和事件冒泡。

事件捕获以点击事件为例,同类型事件会由 根—>目标的祖先元素—>目标的父元素—>目标

元素依次执行

事件冒泡反之****

事件传播****

传播阶段就是事件从触发开始到结束的过程。

优先级:先捕获,再冒泡。

 

什么是事件冒泡,它是如何工作的?如何阻止事件冒泡、默认行为?


工作流程:触发子元素的事件,父元素的‘同名事件’也会被触发

阻止事件冒泡:event.stopPropagation()

阻止默认事件:e.preventDefault()

 

 

JavaScript 动画和 CSS3 动画有什么区别?

1、CSS 动画

对比js优点:

1 requestAnimationFrame 会把所有 DOM 操作集中起来,在一 次重绘或回流中就完成,并且重绘或回流的时间紧跟随浏览器的刷新频率,一般来说,这个频率为每秒 60 帧。

2 在隐藏或不可见的元素中 requestAnimationFrame 不会进行重绘或回流, 就意味着更少的cpu,gpu 和内存使用量。

3 代码相对简单,性能调优方向固定

4 对于帧速表现不好的低版本浏览器,CSS3 可以做到自然降级,而 JS 则需要重新写额外代码

 

缺点:

1  运行过程控制较弱,CSS 动画只能暂停,不能在动画中寻找一个特定的时间点,不能在半路反转动画,不能变换时间尺度,不能在特定的位置添加回调函数或是绑定回放事件,无进度报告。

2  代码冗长。想用 CSS 实现稍微复杂一点动画,最后 CSS 代码都会变得非常笨重。

 

1、JS 动画*

优点:

1 JavaScript 动画控制能力很强,

2 动画效果比 css3 动画丰富,有些动画效果,比如曲线运动,冲击闪烁,视差滚动效果,

只有 JavaScript 动画才能完成。

3 CSS3 有兼容性问题,而 JS 大多时候没有兼容性问题。

 

缺点:

1  Js 在浏览器的主线程中运行,而主线程中还有其它需要运行的js脚本、样式计算、布局、绘制任务等,对其干扰导致线程可能出现阻塞,从而造成丢帧的情况。

2 代码的复杂度高于 CSS 动画

 

event 对象的常见应用?

event.preventDefault(); // 阻止默认行为

event.stopPropagation(); // 阻止冒泡

event.stopImmediatePropagation(); 按钮绑定了 2 个响应函数,依次注册 a,b,点击按钮,a 事件中加 event.stopImmediatePropagation()就能阻止 b 事件

event.currentTarget // 当前绑定的事件

event.target 获取当前元素

 

通用事件绑定/ 编写一个通用的事件监听函数?

function bindEvent(elem, type, selector, fn) {

    if (fn == null) {

      fn = selector;

      selector = null;

    }

    elem.addEventListner(type, function (e) {

      var target;

      if (selector) {

        target = e.target;

        if (target.matches(selector)) {

          fn.call(target, e);

        }

      } else {

        fn(e);

      }

    })

  }
    // 使用代理

  var div1 = document.getElementById('div1');

  bindEvent(div1, 'click', 'a', function (e) {

    console.log(this.innerHTML);

  });

  // 不使用代理

  var a = document.getElementById('a1');

  bindEvent(div1, 'click', function (e) {

    console.log(a.innerHTML);

  })

DOM 和 BOM 的区别

BOM 是 Browser Object Model 的缩写,即浏览器对象模型。BOM 没有相关标准。 本质是window

DOM 是 Document Object Model 的缩写,即文档对象模型。W3C 的标准。最根本window.document

 

 

事件三要素

事件源、事件类型、事件处理函数

 

事件执行过程

事件捕获,事件冒泡

 

获取元素位置


offsetParent:是指当前元素最近的经过定位的父级元素如果没有则一直向上直至 body。

offsetWidth/offsetHeight: width+padding+border

clientLeft/clientTop:表示内容区域的左上角相对于整个元素左上角的位置

scrollWidth:获取对象的滚动宽度

scrollHeight: 获取对象的滚动高度。

scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离

scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离

window.screen.availHeight/window.screen.availWidth: 浏览器去除上方工具栏和下放

菜单栏可用宽高

window.screen.height/window.screen.width: 屏幕宽高

2、event.clientX 和 event.clientY

事件相对于浏览器窗口的水平和垂直距离

3、getBoundingClientRect

方法返回一个一个矩形对象,包含四个属性:left、top、right 和 bottom。分别表示元素

各边与页面上边和左边的距离

 

封装运动函数


 /*

  obj 指的是 DOM 对象

  - json 指的是 CSS 样式

  例 startMove(oDiv,{width:100,height:100},function(){})

  */

    function startMove(obj, json, fnEnd) {

      clearInterval(obj.timer); //先清除之前的定时器

      obj.timer = setInterval(function () {

        var bStop = true; // 假设所有的值都到了

        for (var attr in json) { //遍历 json 属性

          var cur = (attr == 'opacity') ?

            Math.round(parseFloat(getStyle(obj, attr)) * 100) : parseInt(getStyle(obj, attr)); //对 opacity

          特殊处理

          var speed = (json[attr] - cur) / 6;

          speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //speed 数字

          转化,防止不能到达目标的 bug

          if (cur != json[attr]) bStop = false; //如果没有达到目标值,则 bStop 设为

          false;

          if (attr == 'opacity') {

            obj.style.filter = 'alpha(opacity=' + (cur + speed) + ')';

            obj.style.opacity = (cur + speed) / 100;

          } else {

            obj.style[attr] = cur + speed + 'px';

          }

        }

        if (bStop) {

          clearInterval(obj.timer);

          if (fnEnd) fnEnd(); //执行回调函数

        }

      }, 30);

    }

    function getStyle(obj, name) {

      return obj.currentStyle ? obj.currentStyle[name] :

        window.getComputedStyle(obj, null)[name]; //浏览器兼容性处理,注意 getComputedStyle 为只读属性

    }

    function getByClass(oParent, sClass) {

      var aEle = oParent.getElementsByTagName('*');

      var aResult = [];

      var re = new RegExp('\\b' + sClass + '\\b', 'i');

      for (var i = 0; i < aEle.length; i++) {

        if (re.test(aEle[i].className)) aResult.push(aEle[i]);

      }

      return aResult;

    }

 

绑定事件和解除事件的区别

1、事件绑定

定义:一个事件可以加多次,且不会覆盖

 

 

2、绑定方法

addEventListener (事件名,函数名,false)

removeEventListener()

 

谈谈事件委托的理解?

什么是事件委托?给父元素注册事件,委托给子元素处理