This article has participated in the activity of “New person creation Ceremony”, and started the road of digging gold creation together.

preface

I didn’t take the time to sort out the H5 content before and make notes for summary use.

The record includes some new tags, attributes, and new apis.

There are also front and back detailed use cases for drag and drop, Web Workers, SSE and NodeJS, WebSocket and NodeJS.

Canvas and inline SVG

canvas

  1. Custom graphics chart, based on JS drawing API to describe 2D graphics.
  2. Render it pixel by pixel, so once rendered it won’t be noticed by the browser, but it can be redrawn with requestAnimationFrame to animate the page.
<body>
    <canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;">
    </canvas>
</body>

<script>
    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    ctx.fillStyle = "#FF0000";
    ctx.fillRect(0.0.150.75);
</script>
Copy the code

svg

  1. Is a language that uses XML to describe 2D graphics.
  2. Each graph that is drawn is considered an object. If the attributes of an SVG object change, the browser can reproduce the graphics automatically.
    <svg height="190">
        <polygon points="100,10, 40,180, 190,60, 10,60, 160,180"
            style="fill:lime; stroke:purple; stroke-width:5; fill-rule:evenodd;">
    </svg>
Copy the code

LocalStorage localStorage and sessionStorage

  1. Local storage, caches some data in the browser.
  2. LocalStorage and sessionStorage difference is that sessionStorage is only valid for one session, close the browser and open the invalid, while localStorage is still valid unless manually cleared.
  3. Different from cookies, Storage will not be transmitted to the server, and the Storage content is relatively large, cookie can be stored content is relatively small.
// Store the value of localStorage
window.localStorage.setItem("local"."localValue")
// The value of localStorage
const local = window.localStorage.getItem('local')
console.log(local)

// sessionStorage
window.sessionStorage.setItem("session"."sessionValue")
// The value of sessionStorage
const session = window.sessionStorage.getItem('session')
console.log(session)
Copy the code

requestAnimationFrame

  1. Raf for short, as you might be asked in an interview.
  2. Use method: Call requestAnimationFrame(fun) in the declared function fun.
  3. In contrast to the setTimeout implementation animation, raf runs according to the browser’s drawing frequency, so it looks smooth without dropping frames.
    const raf = () = > {
        / /... Perform content
        requestAnimationFrame(raf)
    }
    raf()
Copy the code

Media labels Video and Audio

  • Audio and video, H5 embedded audio and video use of the label, more convenient.
<video width="320" height="240" controls>
  <source src="movie.mp4" type="video/mp4">
  <source src="movie.ogg" type="video/ogg">Your browser does not support the Video TAB.</video>
Copy the code
<audio controls>
  <source src="horse.ogg" type="audio/ogg">
  <source src="horse.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
Copy the code

Drag and drop content

The content being dragged

  1. adddraggable="true"Is allowed to be dragged and dropped.
  2. addondragstartEvent represents the data stored during drag and drop. Event can be used as an input parameter to facilitate the use of information.
    <img id="drag" src="./xx.jpg" draggable="true" ondragstart="drag(event)" width="336" height="69">
Copy the code
  1. event.dataTransfer.setDataWe can store information about what we’re dragging and dropping, we can store the ID, the key, the value.
    function drag(e) {
        e.dataTransfer.setData("Text", e.target.id);
    }
Copy the code

A container or location for storing content

  1. Drag and drop is not allowed by default, so we’re going to giveondragoverandondropEvent add blocks default events.
  2. addondropEvent, this is the event that is triggered when the mouse drags something over the container and releases it, it can be usede.dataTransfer.getDatareadondragstartUsed in eventsevent.dataTransfer.setDataStored values.
  3. Select the content to be placed with the ID and let the container call itappendChildAdd content to your content area.
    <div id="box" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
Copy the code
    function allowDrop(e) {
        e.preventDefault();
    }
Copy the code
    function drop(e) {
        e.preventDefault();
        var id = e.dataTransfer.getData("Text");
        e.target.appendChild(document.getElementById(id));
    }
Copy the code

The principle of

  1. As long as the drag-and-drop content is addeddraggable="true", as it isappendChildWhen the call adds something else, backflow occurs, making the original content disappear, giving a drag-and-drop effect.
  2. I tried to manually add buttons without dragging, and found that as long as the above conditions are met, even if the dragging event of the dragged element is deleted, the effect can be achieved, moving from the original position to the target container position.
    <button onclick="test()">Click on the try</button>
Copy the code
    function test() {
        document.getElementById('box').appendChild(document.getElementById('drag'))}Copy the code

Complete sample

<style>
    #box {
        width: 350px;
        height: 70px;
        padding: 10px;
        border: 1px solid #aaaaaa;
    }
</style>
<body>
    <p>Drag an image into a rectangle:</p>

    <div id="box" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
    <br>
    <img loading="lazy" id="drag" src="./xxx.jpg" ondragstart="drag(event)"
        draggable="true" width="336" height="69">
    <button onclick="test()">Click on the try</button>
</body>
<script>
    function allowDrop(e) {
        e.preventDefault();
    }

    function drag(e) {
        e.dataTransfer.setData("Text", e.target.id);
    }

    function drop(e) {
        e.preventDefault();
        var data = e.dataTransfer.getData("Text");
        e.target.appendChild(document.getElementById(data));
    }

    function test() {
        document.getElementById('box').appendChild(document.getElementById('drag'))}</script>
Copy the code

Geographic location acquisition

  1. navigator.geolocation.getCurrentPositionGets the position as a function.
  2. The function takes position, latitude and longitudeposition.coords.longitudeandposition.coords.latitude.
<body>
  <p id="demo">Click the button to get your current coordinates (it may take a long time to get them) :</p>
  <button onclick="getLocation()">Am I</button>
  <script>
    var x = document.getElementById("demo");
    function getLocation() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition);
      }
      else {
        x.innerHTML = "This browser does not support geolocation."; }}function showPosition(position) {
      x.innerHTML = "Latitude:" + position.coords.latitude +
        

Longitude:
+ position.coords.longitude; }
</script> </body> Copy the code

New semantic tags

Header, section, footer, aside, nav, main, article, figure

New input type

Color, date, datetime, datetime-local, email, month, number, range, search, tel, time, URL, week

New form elements

datalist

  1. willinputthelistProperties anddatalisttheidSet to the same to bind the input to a box for input,listProperty is also a new form property for H5.
    <input list="listName">

    <datalist id="listName">
        <option value="value1">
        <option value="value2">
        <option value="value3">
        <option value="value4">
        <option value="value5">
    </datalist>
Copy the code

output

  1. Used for different types of output, such as computational or script output
<form oninput="x.value=parseInt(a.value)+parseInt(b.value)">0
<input type="range" id="a" value="50">100 +
<input type="number" id="b" value="50">=
<output name="x" for="a b"></output>
</form>
Copy the code

New form properties

(Already common)

  1. Common in number: min, Max, step.
  2. Common in file: multiple.
  3. Related to datalist: list.
  4. Others: Autofocus, Multiple, placeholder, Required, Pattern, height, width.

(Uncommon vs. uncommon)

autocomplete

  1. You can add this attribute to form and input to determine whether or not it is auto-complete. If you add true to form, all input is auto-complete, but you can add false to input separately, which takes precedence.
  2. The autocomplete effect is input data that was submitted, and when you enter the form again, you may be prompted for past input.
  3. Some browsers have this feature automatically; others need to be added manually.
<form action="demo" autocomplete="on">
  name:<input type="text" name="fname"><br>
  E-mail: <input type="email" name="email" autocomplete="off"><br>
  <input type="submit">
</form>
Copy the code

novalidate

  • Form adding this attribute will no longer filter input, for exampletype="email"Input also allows arbitrary input.
<form action="demo" novalidate>
  E-mail: <input type="email" name="user_email">
  <input type="submit">
</form>
Copy the code

other

There are also some attributes that override form attributes, which are not commonly used by individuals and are interested in querying for themselves: Form, FormAction, FormencType, FormMethod, FormNovalidate, and FormTarget.

Application cache

  1. Add to the HTML tagmanifest="demo.appcache"And created in HTML cognatedemo.appcacheThe Manifest file can be cached, visited the page, offline again can still access.
  2. The Manifest file is used to configure the contents to be cached, and the version is added so that the cache can be updated better.
  3. The cache capacity is limited.

demo.appcache

CACHE MANIFEST
#v0. 01.
/index.html
/...
/...
Copy the code

Web Workers

  1. Js running in the background does not affect page performance.
  2. Check whether the user’s browser supports it.
    if (typeof(Worker) ! = =undefined) {
        console.log('Support for Web workers')}Copy the code
  1. Write the JS file to run externally, that is, the Web worker file.
// test.js
let i = 0

setInterval(() = > {
  i++
  //postMessage passes data
  postMessage(i)
}, 1000)
Copy the code
  1. Receive in HTML page,onmessageListening for web worker filespostMessageEvent, one in the onMessage parameter eventdataThe attribute comes from postMessage.
    let w
    if (typeof(Worker) ! = =undefined) {
        w = new Worker("/test.js")
    }
    w.onmessage = (event) = > {
        console.log(event.data)/ / 1... 2... 3...
    }
Copy the code
  1. w.terminate()Termination of the Web Worker
<body>
    <button onclick="start()">Use the Web Worker</button>
    <button onclick="stop()">Termination of the Web Worker</button>
</body>
<script>
    let w
    const start = () = > {
        if (typeof(Worker) ! = =undefined) {
            w = new Worker("/test.js")
        }
        w.onmessage = (e) = > {
            console.log(e.data)
        }
    }

    const stop = () = > {
        w.terminate();
    }
</script>
Copy the code
  1. Note that HTML opened from a local file does not support Web workers and is best deployed, such as using the Nginx proxy for static pages.

Server-sent Events (NodeJS case)

  • SEE for short, the server sends events, the web page automatically gets updates from the server, one-way messaging.

Write the NodeJS server

  1. Create a service on port 8844, I’ll call it /stream, I’ll use Express, or HTTP if you don’t like it.

  2. Res. set request header Settings are key, ‘content-type ‘: ‘text/event-stream’ is a must for SSE,’ access-Control-allow-origin ‘: ‘*’ to make cross-domain testing easy.

  3. Res.write pushes messages. Send is definitely not used because you want to keep the connection alive.

import express from 'express'
const app = new express()
app.use(express.json())

app.get('/stream'.(req, res) = > {
  res.set({
    'Content-Type': 'text/event-stream'.'Cache-Control': 'no-cache'.Connection: 'keep-alive'.'Access-Control-Allow-Origin': The '*',
  })

  res.write('retry: 10000\n')
  res.write('event: connecttime\n')
  res.write('data: ' + new Date() + '\n\n')
  res.write('data: ' + new Date() + '\n\n')

  let interval = setInterval(function () {
    res.write('data: ' + new Date() + '\n\n')},1000)

  req.connection.addListener(
    'close'.function () {
      clearInterval(interval)
    },
    false
  )
})

app.listen(8844.() = > {
  console.log('open')})// Here are the scenarios that use HTTP, similarly

// import http from 'http'
// http
// .createServer(function (req, res) {
// var fileName = '.' + req.url

// if (fileName === './stream') {
// res.writeHead(200, {
// 'Content-Type': 'text/event-stream',
// 'Cache-Control': 'no-cache',
// Connection: 'keep-alive',
// 'Access-Control-Allow-Origin': '*',
/ /})
// res.write('retry: 10000\n')
// res.write('event: connecttime\n')
// res.write('data: ' + new Date() + '\n\n')
// res.write('data: ' + new Date() + '\n\n')

// let interval = setInterval(function () {
// res.write('data: ' + new Date() + '\n\n')
/ /}, 1000)

// req.connection.addListener(
// 'close',
// function () {
// clearInterval(interval)
/ /},
// false
/ /)
/ /}
/ /})
/ / listen (8844, '127.0.0.1)

Copy the code

Front-end HTML page

  1. New EventSource (' http://127.0.0.1:8844/stream ')Request the corresponding service.
  2. Add several listeners to get messages pushed by the server.
<body>
  <div id="example"></div>
</body>
<script>
  if (typeof(EventSource) ! = ="undefined") {
    // Browsers support server-sent
    var source = new EventSource('http://127.0.0.1:8844/stream');
    var div = document.getElementById('example');

    source.onopen = function (event) {
      div.innerHTML += '

Connection open ...

'
; }; source.onerror = function (event) { div.innerHTML += '<p>Connection close.</p>'; }; source.addEventListener('connecttime'.function (event) { div.innerHTML += ('<p>Start time: ' + event.data + '</p>'); }, false); source.onmessage = function (event) { div.innerHTML += ('<p>Ping: ' + event.data + '</p>'); }; }
</script> Copy the code

WebSocket (NodeJS case)

  • The WebSocket protocol defined by HTML5 can better save server resources and bandwidth, and can communicate in more real time.

Write the NodeJS server

  1. Nodejs has a number of WebSocket support packages, which are used herenodejs-websocket.
  2. ws.createServerCreate a service that listens for three events, close and error, and text that listens for messages passed from the previous client.
  3. sendTextIt is used to deliver messages to clients to achieve bidirectional communication.
import ws from 'nodejs-websocket'

console.log('Start establishing connections... ')

const server = ws
  .createServer(function (conn) {
    conn.on('text'.function (str) {
      console.log('Message received from client :' + str)
      conn.sendText('Message from server: Received')
    })
    conn.on('close'.function (code, reason) {
      console.log('Close connection')
    })
    conn.on('error'.function (code, reason) {
      console.log('Abnormal shutdown')
    })
  })
  .listen(8001)

console.log('WebSocket setup completed ')
Copy the code

Front-end HTML page

  1. new WebSocketConnect the WS service port, remember to add before the servicews:.
  2. ws.sendSends a message to the server.
  3. ws.onmessageListen, you can wait here at any time for the server to send a message back.
<body>
  <div id="mess">Connecting...</div>
  <div class="values">
    <div class="value" id="value1">watermelon</div>
    <div class="value" id="value2">apple</div>
    <div class="value" id="value3">pears</div>
  </div>
  <script>
    const mess = document.getElementById("mess");
    if (window.WebSocket) {
      const ws = new WebSocket('ws://localhost:8001');

      ws.onopen = function (e) {
        console.log("Server connection successful");
        ws.send("Vadasi has connected to the server.");
      }
      ws.onclose = function (e) {
        console.log("Server down");
      }
      ws.onerror = function () {
        console.log("Connection error");
      }

      ws.onmessage = function (e) {
        mess.innerHTML = "Connection successful"
        console.log(e)
      }

      document.querySelector(".values").onclick = function (e) {
        const time = new Date(a); ws.send(time +"Click" + e.target.innerHTML + "" "); }}</script>
</body>

Copy the code