JS-Web-API考点和重点面试题

115 阅读7分钟

本篇会产出基础BOM(Browser Object Modal)操作、事件绑定、事件冒泡机制、事件代理。事件能让网页和鼠标、键盘进行交互,还有ajax相关的知识点。包括XMLHttpRequest、同源策略、跨域方式以及常用的插件。还有存储方面,包含cookie、localStorage和sessionStorage。

一、BOM操作相关面试题##

1、如何识别浏览器的类型

可以使用navigator对象的属性来获取。navigator.userAgent:返回浏览器的user-agent字符串,包含了浏览器的名称、版本、操作系统等信息。 也可以通过解析user-agent字符串来判断浏览器类型。

2、分析拆解url各个部分

要分析url的各个部分,可以使用BOM中的location对象。

location对象包含当前窗口的URL信息,它有以下属性:

location.href:当前页面的完整URL地址,包括协议、主机、路径和查询字符串。
location.protocol:当前页面使用的协议,例如http或https。
location.host:当前页面的主机名和端口号,例如www.example.com:80 
location.hostname:当前页面的主机名,例如www.example.com
location.port:当前页面的端口号,例如80
location.pathname:当前页面的路径部分,例如/path/to/page.html
location.search:当前页面的查询字符串部分,例如?id=123&name=John
location.hash:当前页面的锚点部分,例如:#section1

3、BOM中的screen和history属性

screen属性提供了有关用户屏幕的信息,例如屏幕的宽度和高度,屏幕的颜色深度等等。 history属性提供了浏览器的历史记录,即用户在浏览器中访问过的所有网页。使用history属性,可以在JavaSCript代码中控制浏览器的后退和前进按钮,实现页面的跳转和导航。例如history.back()方法返回上一个页面,使用history.forward()方法前往下一个页面或者history.go()方法前端制定的页面。

二、DOM事件绑定、事件冒泡、事件代理相关面试题##

1、编写一个通用的事件监听函数

function addEventHandler(element, eventType, handler) {
  if (element.addEventListener) {
    element.addEventListener(eventType, handler, false);
  } else if (element.attachEvent) {
    element.attachEvent("on" + eventType, handler);
  } else {
    element["on" + eventType] = handler;
  }
}

示例如下:

var myButton = document.getElementById('myButton');
function handlerClick() {
    alert('Button clicked!')
}
addEventHandler(myButton,'click',handlerClick)

2、描述事件冒泡的流程

在DOM中,事件冒泡是一种事件传递的机制,它从最具体的元素开始,然后逐级向上传递到较为抽象的元素,直到最终到达文档的根节点。

具体流程如下: 当一个事件在某个元素上发生时,该元素会首先处理该事件。这个处理过程可能会触发元素的事件监听器,或者执行该缘故的默认行为。 如果该元素上的事件监听器没有阻止事件传递,那么该事件会向该元素的父元素传递。这个传递过程会重复第一步,即父元素会首先处理该事件,并且可能会触发父元素上的事件监听器或默认行为。 如果父元素上的事件监听器没有阻止事件传递,那么该事件会继续向上传递到更高层次的祖先元素,这个传递过程会重复第一步,直到事件到达文档的根节点。 如果根节点上的事件监听器没有阻止事件传递,那么该事件就会被传递到浏览器中,由浏览器处理。

需要注意的是,事件冒泡时DOM事件传递机制的默认行为,但是可以通过调用事件对象的stopPropagation()方法来阻止事件冒泡。此外,还可以使用事件对象的preventDefault()方法来阻止事件的默认行为。

3、无限下拉的图片列表,如何监听每个图片的点击?

可以使用事件代理(Event Delegation)的方法。事件代理是指事件处理程序绑定到其父元素上,而不是绑定到每个子元素上。当子元素触发事件时,事件会冒泡到父元素,从而触发父元素上的事件处理程序。这样可以避免为每个字元素单独绑定事件处理程序,提高性能和代码可维护性。

具体代码,例如:

//给父元素绑定点击事件处理
const parent = document.querySelector('#parent')
parent.addEventListener('click', handleClick)

//发事件的目标元素是否为图片,如果是则执行相应的操作,例如:
function handleClick(event) {
    const target = event.target;
    if(target.tagName == 'IMG') {
        //执行点击图片的操作
    }
}

//如果无限下拉的图片列表时通过异步加载数据实现的,可以在加载新数据后重新绑定事件处理程序,例如:
function loadMoreData() {
    //异步加载新数据
    //。。。
    //加载完成后重新绑定事件处理程序
    parent.removeEventListener('click', handleClick)
    parent.addEventListener('click', handleClick)
}


//如果图片列表中的图片是动态生成的,可以在生成图片时给每个图片绑定一个唯一的标识符,例如自定义的data属性,然后在事件处理程序中根据标识符来判断点击的是哪个图片,例如:
function generateImage(url) {
    const img = document.createElement('img')
    img.src= url;
    img.setAttribute('data-id', generateUniqueId())//给图片设置一个唯一标识符
    parent.appendChild(img);
}

function
 handleClick(event) {
    const target = event.target;
    const id = target.getAttribute('data-id');//获取点击图片上的标识符
    if(id) {
        //根据标识符执行相应的操作
    }
 }

三、 ajax相关的面试题

1、手写一个简易的ajax

 function ajax(url) {
    const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open('GET',url,true)
        xhr.onreadystatechange = function() {
            if(xhr.readyState ===4) {
                if(xhr.status === 200) {
                    resolve(xhr.responseText)
                }else if(xhr.status === 404) {
                    reject(new Error('404'))
                }
            }
        }

        xhr.send(null)
    })

    return p
 }

//这个是事例
 const url = 'data/text.json'
 ajax(url)
 .then((data)=>{
    console.log(data)
 }).catch(err => {
    console.error(err)
 }) 

2、跨域的常用实现方式

(1)JSONP

它的原理是利用script标签的src属性可以跨域访问的特性,将需要跨域获取的数据封装在一个函数中,然后通过script标签的src属性运入这个函数。这种方式只能用于GET请求,并且要求返回的数据必须是JSON格式。

(2)CORS

它需要在服务端设置响应头,允许制定的域名访问数据。在客户端中,只需要发送普通的XMLHttpRequest请求即可,无需做任何特殊处理。

(3)代理

它的原理是在同域下搭建一个代理服务器,将需要跨域获取的数据请求发送到代理服务器,再由代理服务器向目标服务器发送请求,获取数据后再返回给客户端。

(4)postMessage

它是HTML5中引入的,在不同窗口件传递消息。在客户端中,可以通过window.postMessage方法向其他窗口发送消息,其他窗口可以通过监听message事件来接受消息。

(5)WebSocket

它是HTML5引入的新协议,可以在客户端和服务端之间建立一个双向通信的通道。WebSocket可以支持跨域通信,但需要服务端支持。

(6)document.domain

如果两个页面的域名只有二级域名不同,可以通过设置document.domain,并且二级域名必须相同。

(7)location.hash

通过改变URL的hash值,可以实现不同页面之间的通信。需要在不同页面使用JavaScript监听hashchange事件,并且需要约定好hash值的格式。

四、浏览器存储相关面试题

1、如何理解cookie

  • 本身用于浏览器和服务端通讯
  • 被“借用”到 本地存储来用
  • 可用document.cookie=‘...’来修改

cookie可以分为两种类型:会话cookie和 持久cookie。会话cookie只存储在浏览器 中,直到 关闭浏览器为止。持久cookie是存储在设备中 ,在指定的时间内保留。

还有cookie需要注意隐私和安全问题,因为cookie中包含大量用户信息,可以用于追踪用户行为或进行网络钓鱼攻击。因此浏览器通常提供了一些隐私设置,来控制cookie使用。

cookie的缺点:

  • 存储大小,最大4kb
  • http请求时需要发送到服务端,增加请求数据量
  • 只能用document.cookie='...';来修改,API太过简陋。不好理解

2、localStorage和SessionStorage和cookie的区别

localStorage和sessionStorage的特点:

  • HTML5定义,最大可存5MB
  • API简单易用setItem和getItem
  • 不会随着http请求被发送出去

localStorage数据会永久存储,除非代码或手动删除 sessionStorage数据只存在于当前会话,浏览器关闭则清空

区别:

  • 容量

  • API易用性

  • 是否跟随http请求发送