2020-题目(HTML5)

2020题目(2)

1.DOCTYPE的作用?标准模式与兼容模式的区别?

DOCTYPE位于html文档第一行,处于html标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。
标准模式的排版和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为,以防止站点无法工作。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
</body>
</html>

2.页面导入样式时,使用link和@import有什么区别?

1) 用途:

  • @import只能引入CSS文件
  • link既能引入CSS,又能引入其他文件,比如vue脚手架唯一index.html中引入.ico图标
<link rel="icon" href="<%=BASE_URL%>favicon.ico" >

2) 加载顺序

  • @import引入的CSS将在页面加载完毕后,被加载
  • link标签引入的CSS在页面加载时,被同时加载。所以一般把link放在html文档开头,从而css加载和html加载能够并行进行

3) 优先级

  • @import引入的CSS样式优先级 低于 link引入的CSS样式

4) DOM操作

  • @import不支持使用DOM动态添加和改变
  • link支持使用DOM动态添加和改变

3.对浏览器内核的理解

主要分为渲染引擎和JS引擎

  • 渲染引擎:负责取得网页的内容(HTML、XML、图像等)、整理讯息(如加入CSS等),以及计算网页的显示方式,然后会输出至显示器。浏览器内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。
  • JS引擎:解析和执行JavaScript来实现网页的动态效果

4.常见的浏览器内核种类

  • Trident 内核:IE、360、搜狗浏览器等
  • Gecko 内核:Firefox
  • Webkit 内核:Safari、Chrome、Edge、Opera

5.HTML5新特性

  • 增强了图形渲染:canvas
  • 音影:video、audio
  • 数据存储:sessionStorage、localStorage
  • 语义化更好的元素内容:article、footer、header、nav、section等
  • 表单控件:calendar、date、time、email、url、search
  • 新的技术:webworker(专用线程)、websocket通信、Geolocation地理定位

6.HTML5移除的元素

  • <basefont> 默认字体,不设置字体,以此渲染
  • <font> 字体标签
  • <center> 水平居中
  • <u> 下划线
  • <big> 大字体
  • <strike> 中横线
  • <tt>文本等宽
  • 框架集:<frameset>、<noframes>、<frame>

7.如何处理HTML5新标签的兼容性

  • 使用框架html5shiv,可解析不兼容标签并且自动添加行为
<script>
src = "http://html5shim.googlecode.com/svn/trunk/html5.js
</script>
  • 不使用框架情况下,通过document.createElement创建标签,自定义对应样式和事件

8.对HTML语义化的理解

  • 用正确的标签做正确的事
  • HTML语义化让页面的内容结构化,结构更清晰,便于浏览、便于搜索引擎解析
  • 搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO
  • 使阅读源代码的人更容易将网站分块,便于阅读维护理解

9.[重要]cookie、sessionStorage、localStorage

相同点:都存储在客户端

不同点:

1) 存储大小
  • cookie 数据大小不能超过4k
  • sessionStorage和localStorage 数据大小可以达到5M或更大
2) 有效时间
  • cookie 在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
  • localStorage 存储持久数据,浏览器关闭后数据不丢失,除非主动删除数据
  • sessionStorage 数据在当前浏览器窗口关闭后自动删除
3) 数据与服务器之间的交互方式
  • cookie 的数据会自动传递到服务器,服务器端也可以写cookie到客户端
  • sessionStorage和localStorage 不会自动把数据发给服务器,仅在本地保存
4)实时性(如在多个标签页实现通信时)
  • cookie 不具备实时性,cookie值改变后只能手动获取或者用setInterval定时获取修改后的cookie值
  • localStorage 只要任一同源页面修改了localStorage中的值,都会自动触发其他页面中的storage事件

10.iframe的缺点

  • iframe会阻塞主页面的onload事件
    因为页面加载时,如果遇到iframe,会先去加载iframe页面,等待iframe加载回来后再继续往下加载,从而导致总体加载时间过长
  • 搜索引擎的检索程序无法解读这种页面,不利于SEO
  • iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载
  • iframe和主页面属于两个页面,意味着有两个window对象,iframe破坏了程序和页面的结构
    如需使用iframe,最好通过JavaScript动态给iframe添加 src 属性值,这样可以绕开以上两个问题。
    如果网页有公用的页头/页尾,可先使用<header>展位,ajax异步加载页头/页尾,可改善页面加载时间过长问题

11.网页验证码的作用

  • 是为了防止一些人使用软件恶意注册、发帖等行为而设的
  • 它的行为是为了确保登陆网站的是一个真人,而不是一个自动登陆的软件
    例:破解密码时可以穷举所有密码组合,而这种暴力破解密码的前提是可以连续不间断的向服务器发送请求,但是验证码破坏了这一前提

12.[重要]如何实现浏览器内多个标签页之间的通信

1) cookie + setInterval 方式

注: cookie、localStorage、sessionStorage在同源页面间属于共享资源。(同源:如两个页面的协议、IP地址、端口号相同,即为同源页面)
缺点:
① cookie 空间有限,浏览器在每个域名下最多能设置30-50个cookie,容量最多4k左右
② 每次 HTTP 请求会把当前域的所有cookie发送到服务器上,包括只在本地才用到的。浪费网络带宽
③ setInterval的频率设置,过大会影响浏览器性能,过小会影响时效性

优点:每个浏览器都兼容

// send.html
send.onclick = function(){
	document.cookie = `msg=${msg.value.trim()}`
}
// rec.html

function getKey(key){ // 获取cookie中的指定变量值
	return JSON.parse(`{"${
		document.cookie.replace(/;\s+/gi,'", "').replace(/=/gi,'":"')
	}"}`)[key]
}

// 每隔1秒获取cookie的内容
setInterval(function(){
	msg.innerHTML = getKey('msg')
},1000)

完整版代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- send.html -->
  <input id="msg1" type="text">
  <input id="msg2" type="text">
  <button id="send">发送</button>
  <script>
    send.onclick = function(){
      if(msg1.value.trim() !== '' && msg2.value.trim()){
        document.cookie = `msg1=${msg1.value.trim()}`
        document.cookie = `msg2=${msg2.value.trim()}`
      }
    }
  </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- rec.html -->
  <h1>收到消息:<span id="recMsg1"></span></h1>
  <h1>收到消息:<span id="recMsg2"></span></h1>
  
  <script>

    console.log(document.cookie)

    function getKey(key){
      // 解析cookie为对象
      var cookies = JSON.parse(`{"${
        document.cookie.replace(/=/g,'":"').replace(/;\s+/g,'", "')
      }"}`)
      return cookies[key]
    }

    setInterval(() => {
      recMsg1.innerHTML = getKey('msg1')
      recMsg2.innerHTML = getKey('msg2')
    }, 500);

  </script>
</body>
</html> 

2) localStorage 方式

setItem时,会自动触发整个浏览器的storage事件,除当前页面之外,所有打开的标签都会受影响

缺点:
① localStorage属于HTML5新特性,高版本的浏览器才支持localStorage这个属性,且不同浏览器localStorage大小限制不统一
② localStorage只能监听非己页面的数据变化,这一点严重影响使用

优点:解决了cookie容量小和时效性不足的问题

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- send.html -->
  <input id="msg1" type="text">
  <input id="msg2" type="text">
  <button id="send">发送</button>
  <script>
    send.onclick = function(){
      if(msg1.value.trim() !== '' && msg2.value.trim()){
       localStorage.setItem('msg1', msg1.value.trim())
       localStorage.setItem('msg2', msg2.value.trim())
      }
    }
  </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- rec.html -->
  <h1>收到消息:<span id="recMsg1"></span></h1>
  <h1>收到消息:<span id="recMsg2"></span></h1>
  
  <script>

    // 页面加载时调用函数
    load()

    // 只要任一同源页面修改了localStorage中的值,都会自动触发其他页面中的storage事件
    window.addEventListener('storage', function(){
      load()
    })
    // window.addEventListener('storage',load) // 不涉及this情况下,可直接这样写

    // 函数:获取localStorage中的值
    function load(){
      recMsg1.innerHTML = localStorage.getItem('msg1')
      recMsg2.innerHTML = localStorage.getItem('msg2')
    }

  </script>
</body>
</html> 

3)WebSocket 方式

2020-题目(HTML5)

缺点:
① 它需要服务端的支持才能完成任务。如果socket数据量比较大的话,会严重消耗服务器的资源
② 必须要在服务端项目中写服务端监听程序才能支持

优点:如果部署了WebSocket服务器,可以实现很多实时的功能。(如阿里旺旺等网页上的即时通信功能)

实现步骤:
① 实现服务端监听程序

npm init

先创建一个node项目,然后引入ws

npm i -s ws

新建js文件,实现功能代码如下:

// 获得 WebSocketServer 类型
var WebSocketServer = require('ws').Server

// 创建 WebSocketServer 对象实例,监听指定端口
var wss = new WebSocketServer({port:5500})

// 创建保存所有已连接到服务器的客户端对象的数组
var clients = []

// 为服务器添加connection事件监听,当有客户端连接到服务端时,立刻将客户端对象保存进数组中
wss.on('connection', function(client){
  console.log('一个客户端连接到服务器')
  
  if(clients.indexOf(client) === -1){
    clients.push(client)
    console.log(`有${clients.length}个客户端在线`)

    // 为每个client对象绑定message事件,当某个客户端发来消息时,自动触发
    client.on('message', function(msg){
      console.log(`收到消息:${msg}`)

      // 遍历clients数组中每个其他客户端对象,并发送消息给其他客户端
      for(var c of clients){
        if(c != client){
          c.send(msg)
        }
      }
    })
  }
  
})

② 实现发送端代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- send.html -->
  <input type="text" id="msg">
  <button id="send">发送</button>
  <script>
    // 建立到服务端的WebSocket连接
    var ws = new WebSocket('ws://localhost:5500')

    send.onclick = function(){ // 点击“发送”按钮,向服务端发送信息
      if(msg.value.trim() !== ''){
        ws.send(msg.value.trim())
      }
    }
  </script>
</body>
</html>

③ 实现接收端代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- rec.html -->
  <h1>收到消息:<span id="recMsg"></span></h1>
  <script>
    // 建立到服务端的WebSocket连接
    var ws = new WebSocket('ws://localhost:5500')

    // 当连接被打开时,注册接收消息的处理函数
    ws.onopen = function(event){
      console.log(event)
      // 当有消息发过来时,就将消息放到显示元素上
      ws.onmessage = function(event){
        recMsg.innerHTML = event.data
      }
    }
  </script> 
</body>
</html>

④ 运行
运行服务端 node server.js --> 打开发送端和接收端文件 --> 发送消息
2020-题目(HTML5)

4) SharedWorker 方式

2020-题目(HTML5)
实现步骤:
① 创建worker.js,代码如下:

// 在所有SharedWorker共享的worker.js中,保存一个data变量,用于存储多个worker共享的数据
let data = ''

// 必须提供一个名为onconnect的事件处理函数
// 每当一个页面中new SharedWorker('worker.js')时,就会为新创建的worker绑定onconnect事件处理函数
onconnect = function(e){
  // 获得当前连接上来的客户端对象
  var client = e.ports[0]
  // 当当前对象收到消息时
  client.onmessage = function(e){
    if(e.data === ''){ // 如果消息内容为空,说明该客户端想获取共享数据data
      client.postMessage(data) // 给当前客户端发送data数据
    }else{ // 如果消息内容不为空,说明该客户端想要提供新的消息保存在共享的data中
      data = e.data
    }
  }
}

② 创建发送方.html,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- send.html -->
  <input type="text" id="msg">
  <button id="send">发送</button>

  <script>
    var worker = new SharedWorker('worker.js')
    worker.port.start()

    send.onclick = function(){
      if(msg.value.trim() !== ''){
        worker.port.postMessage(msg.value.trim())
      }
    }
  </script>
</body>
</html>

③ 创建接收方.html,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- rec.html -->
  <h1>收到消息:<span id="recMsg"></span></h1>

  <script>
    var worker = new SharedWorker('worker.js')
    // 3.当worker.js中给当前客户端返回了data,会触发当前客户端的message事件,data的值自动保存进事件对象e的data属性中
    worker.port.addEventListener('message',function(e){
      recMsg.innerHTML = e.data
    })
    worker.port.start()

    // 1.接收端反复向共享的worker.js对象中发送空消息,意为想获取data的值
    setInterval(() => {
      worker.port.postMessage('')
      // 2.只要发送消息,就会触发worker.js中的onmessage(),onmessage判断是空消息,说明客户端想获得data,于是就用postMessage()方法,将data返回给当前客户端
    }, 500);
  </script>
</body>
</html>
上一篇:前端sessionStorage&localStorage&cookie使用解析


下一篇:java读取properties文件总结