HTML5脚本编程

HTML5定义了一些新的标记规则,也定义了一些新的JavaScript API,能够让开发人员创建出更好的用户界面。

  • 跨文档消息API 能够在不降低同源策略安全性的前提下,在不同域间的文档间传递消息
  • 原生拖放功能可以指定某个元素可拖动,并在操作系统要放置时做出响应,可以创建可拖动元素及放置目标
  • 媒体元素 <audio><video>拥有自己与音频和视频交互的API,使用canPlayType()检查浏览器是否支持特定格式
  • 历史状态管理可以在不必卸载当前页面时修改浏览器的历史状态栈,在这种机制下,用户可以通过后退和前进按钮在页面状态间切换,这些状态完全由JavaScript控制
1. 跨文档消息传送

window.postMessage() 方法可以安全地实现跨源通信,通常对于两个不同页面的脚本,只有当执行他们的页面位于相同的协议 (通常为https),端口号 (443 为https),以及主机名,两个脚本之间能够相互通信。window.postMessage()方法提供了一种受控机制来规避此限制,只要正确使用,这种方法就很安全。

otherWindow.postMessage(message, targetOrigin, [transfer])
  • otherWindow其它窗口的一个引用,比如iframecontentWidow属性,执行 window.open 返回的窗口对象,或是命名过或数值索引的 window.frames

  • message 将要发送到其它 window 的数据,将会被结构化克隆算法序列化,可以不受限制地将数据对象安全地传送给窗口而无需自己序列化

  • targetOrigin 通过窗口的 origin 属性来指定哪些窗口能接收到消息事件,设置为*时,能够把消息发送给来自任何域的文档

  • 一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方

window.postMessage() 方法被调用时,会在所有页面脚本执行完毕后,向目标窗口派发一个messageEvent消息,data属性为window.postMessage的第一个参数,origin为调用postMessage时消息发送方窗口的originsource为对发送消息的窗口的引用

跨文档消息传送,简称为 XDM,指的是在不同域的页面间传递消息,使用postMessage() 方法,实现一个页面向包含在当前页面中的<iframe>元素或者由当前页面弹出的窗口发送消息,方法的参数为一条消息和一个消息接收方的域名。

2. 原生拖放

拖动元素时,依次触发

  • dragstart
  • drag
  • dragend

当元素被拖动到一个有效的放置目标上时

  • dragenter
  • dragover
  • dragleavedrop

dataTransfer对象是事件对象的属性,用于从被拖动元素向放置目标传递字符串格式的数据,有getData()setData()两个方法。IE中只定义了textURL,HTML5中这两种类型被映射为text/plaintext/uri-list。保存在dataTransfer对象中的数据只能在drop事件处理程序中读取。dataTransfer对象的dropEffect属性可以知道被拖动的元素能够执行哪种放置行为

  • none
  • move
  • copy
  • link

dropEffect属性只与effectAllowed 属性搭配才有用,必须在ondragstart事件处理程序中设置effectAllowed属性

  • uninitialized
  • none
  • copy
  • link
  • move
  • copyLink
  • copyMove
  • linkMove
  • all

对元素设置draggable属性可以设置元素是否可拖动。dataTransfer的其他方法和属性:

  • addElement(ele) 为拖动添加一个元素
  • clearData() 清除以特定格式保存的数据
  • setDragImage(ele, x, y) 指定一副图像,当拖动发生时,显示在光标下方
  • types当前保存的数据类型

腾讯面试 页面内有一个正方形元素 A 和 一个待放置区域 B,对其实现拖拽和放下到 B 区域,并改变 B 区域背景颜色,不可用html5原生事件。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div#a {
            width: 80px;
            height: 80px;
            background-color: green;
            font-size: 20px;
            color: white;
            position: absolute;
            z-index: 2;
        }
        
        div#b {
            width: 200px;
            height: 200px;
            background-color: blueviolet;
            font-size: 20px;
            color: white;
            position: absolute;
            margin-top: 300px;
            z-index: 1;
        }
    </style>
</head>

<body>
    <div id='a'>A</div>
    <div id='b'>B</div>




    <script defer>
        var aModel = document.getElementById('a')
        var bModel = document.getElementById('b')

        var positionAInitial = {
            left: aModel.offsetLeft,
            top: aModel.offsetTop
        }

        var positionB = {
            xL: bModel.offsetLeft,
            xR: bModel.offsetleft + bModel.clientWidth,
            yL: bModel.offsetTop,
            yR: bModel.offsetTop + bModel.clientHeight

        }

        var flag = false
        var inB = false

        aModel.addEventListener('mousedown', function() {
            flag = true
        })

        aModel.addEventListener('mousemove', function(event) {
            if (flag) {
                var position = {
                    x: event.pageX,
                    y: event.pageY
                }
                aModel.style.left = position.x - positionAInitial.left + 'px'
                aModel.style.top = position.y - positionAInitial.top + 'px'
                aModel.opacity = '0.5'
                inB = false

                var positionA = {
                    left: aModel.offsetLeft,
                    right: aModel.offsetLeft + aModel.clientWidth,
                    top: aModel.offsetTop,
                    bottom: aModel.offsetTop + aModel.clientHeight,
                }



                if ((positionA.top <= positionB.yL && positionA.bottom >= positionB.yL) ||
                    (positionA.top <= positionB.yR && positionA.bottom >= positionB.yR) ||
                    (positionA.top >= positionB.yL && positionA.bottom <= positionB.yR)
                ) {
                    inB = true
                }
            }
        })

        aModel.addEventListener('mouseup', function(event) {
            if (inB) {
                aModel.style.opacity = '1'
                bModel.style.backgroundColor = 'yellow'
            } else {
                aModel.style.left = positionAInitial.left + 'px'
                aModel.style.top = positionAInitial.top + 'px'
                aModel.style.opacity = '1'
            }
            flag = false
            inB = false
        })
    </script>
</body>

3. 媒体元素

<audio><video>能够在网页中嵌入跨浏览器的音频和视频内容,允许为媒体创建自定义的控件,并且提供了完善的属性和事件。canPlayType检测浏览器是否支持某种编码解码器。

历史状态管理

通过 history对象进行历史状态管理,可以在不卸载当前页面就能够修改浏览器的历史状态栈,用户能够通过前进和后退按钮在页面状态间切换,这些状态完全由 JavaScript 控制。属性和方法包括:

  • length
  • state
  • back()
  • forward()
  • go()
  • pushState() 将新的状态信息加入历史状态栈
  • replace() 更新当前状态
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容