#JavaScript学习#第十六章:HTML5脚本编程

372 阅读7分钟

Tips: 内容为知识梳理


目录

  1. 跨文档消息传递

  2. 原生拖放

  3. 媒体元素

  4. 历史状态管理


1. 跨文档消息传递

跨文档消息传送(XDM)指的是在不同域的页面间传递消息 用postMessage()方法进行传递,该方法接受两个参数,第一个是要传递的字符串,第二个是表示该字符串接收方来自哪个域的字符串

var iframeWindow = document.getElementById("myframe").contentWindow
iframeWindow.postMessage("some message", "http://www.wrox.com");

例子如上 第二行代码尝试向内嵌框架传递一条信息,并指定框架的文档必须来源于'www.wrox.com',若匹配,则传入信息,否则什么也不做。若把第二个参数改为'*',那么就会匹配来自任何域的文档 当接受到XDM消息时,会触发window对象的message事件,以异步形式触发,事件对象包含三个属性:

  • data:来自于postMessage第一个参数的字符串

  • origin:发送消息的文档所在域

  • source:发送消息的文档的window对象代理,该代理主要用于向原发送方发送回执信息 用以下代码来检测消息来源

      EventUtil.addHandler(window,"message",function(event){
      	if(event.origin == "http://www.wrox.com"){
      		processMessage(event.data);
      	}
      	event.source.postMessage("Received!","http://p2p.wrox.com");
      })
    

2. 原生拖放

2.1 拖放事件

拖动某元素时,依次触发下面事件

  • dragstart
  • drag
  • dragend

按住鼠标键移动鼠标时就触发dragstart事件,通过ondragstart处理程序运行js代码 触发dragstart事件后随即触发drag事件,该事件会被持续触发 拖动结束则触发dragend事件 当元素被拖放到一个有效放置目标上时则依次触发下列事件

  • dragenter
  • dragover
  • dragleave或drop

当元素被拖进放置目标则触发dragenter事件,随即触发dragover事件,只要被拖动元素在目标范围内移动则会持续触发dragover事件,当被拖动元素被拖出目标,则不再发生dragover事件,不过会触发dragleave事件,当被拖动元素放置进目标元素,则触发drop事件

2.2 自定义放置目标

  • 如果拖动元素经过不允许放置的元素,则不会触发drop事件

  • 通过重写dragenter和dragover事件的默认行为,来将元素变为有效放置目标

      var droptarget = document.getElementById("droptarget"); 
    
      EventUtil.addHandler(droptarget, "dragover", function(event){      
      EventUtil.preventDefault(event); 
      }); 
    
      EventUtil.addHandler(droptarget, "dragenter", function(event){     
      EventUtil.preventDefault(event); 
      });
    

以上代码将id名为droptarget的元素变为可放置元素 这样就可以触发drop事件

2.3 dataTransfer对象

它是事件对象的一个属性,用于从被拖动元素向放置目标传递字符串格式的数据。 两个方法:setData和getData,setData接受两个参数,第一个是表示保存的数据类型,第二个是要保存的值,数据类型一般为"text"或"URL",代码如下

//设置和接收文本数据 
event.dataTransfer.setData("text", "some text"); 
var text = event.dataTransfer.getData("text"); 

//设置和接收 URL 
event.dataTransfer.setData("URL", "http://www.wrox.com/"); 
var url = event.dataTransfer.getData("URL"); 

当拖动文本时,浏览器调用setData方法,将文本保存在dataTransfer对象中,拖放链接则保存URL

2.4 dropEffect与effectAllowed

利用dataTransfer对象还可以确定被拖动元素和放置目标能接受什么操作,要访问dataTransfer的两个属性:dropEffect和effectAllowed

  1. dropEffect 通过这个属性知道被拖动元素能执行哪种放置行为,有下列四个可能的值:
  • none:不能把拖动的元素放在这里,这是除文本框外所有元素的默认值

  • move:把拖动元素移动到放置目标

  • copy:把拖动元素复制到放置目标

  • link:放置目标会打开拖动元素,不过必须是一个URL

    该属性必须在ondragenter事件处理程序中设置

  1. effectAllowed 该属性表示允许拖动元素的哪种dropeffect,可能取值如下:
  • uninitialized:没有给被拖动元素设置任何放置行为

  • none:被拖动元素不能有任何行为

  • copy:只允许值为copy的dropeffect

  • link:只允许值为link的dropeffect

  • move:只允许值为move的dropeffect

  • copyLink:允许值为copy和link的dropeffect

  • copyMove:允许值为copy和move的dropeffect

  • linkMove:允许值为link和move的dropeffect

  • all:允许任意dropeffect

    该属性必须在ondragstart设置

2.5 可拖动

元素有一个draggable属性,表示是否可以拖动,通过设置这个属性就可以改变它是否可以拖动

2.6 其他成员

dataTransfer还包含下列方法和属性:

  • addElement(element):为拖动操作添加一个元素。添加这个元素只影响数据(即增加作为拖 动源而响应回调的对象),不会影响拖动操作时页面元素的外观。在写作本书时,只有 Firefox 3.5+ 实现了这个方法。
  • clearData(format):清除以特定格式保存的数据。实现这个方法的浏览器有 IE、Fireforx 3.5+、 Chrome和 Safari 4+。
  • setDragImage(element, x, y):指定一幅图像,当拖动发生时,显示在光标下方。这个方法接收的三个参数分别是要显示的 HTML元素和光标在图像中的 x、y坐标。其中,HTML元素 可以是一幅图像,也可以是其他元素。是图像则显示图像,是其他元素则显示渲染后的元素。 实现这个方法的浏览器有 Firefox 3.5+、Safari 4+和 Chrome。
  • types:当前保存的数据类型。这是一个类似数组的集合,以"text"这样的字符串形式保存着 数据类型。实现这个属性的浏览器有 IE10+、Firefox 3.5+和 Chrome。

3. 媒体元素

<audio><video>元素嵌入视频和音频内容,指定src即可,可以设置width和height属性指定视频播放器大小,为poster属性指定url可以在加载视频内容期间显示一副图像,若标签中有controls属性,则浏览器会显示UI控件方便用户操作媒体,用<source>元素指定src属性,如下所示:

<!-- 嵌入视频 --> 
<video id="myVideo">   
<source src="conference.webm" type="video/webm; codecs='vp8, vorbis'">   
<source src="conference.ogv" type="video/ogg; codecs='theora, vorbis'">   
<source src="conference.mpg">   
Video player not available. 
</video>  
<!-- 嵌入音频 --> 
<audio id="myAudio">   
<source src="song.ogg" type="audio/ogg">   
<source src="song.mp3" type="audio/mpeg">   		
	Audio player not available. 
</audio>

3.1 属性

下面是两个元素共有的属性

3.2 事件

以下是媒体元素相关的事件

3.3 自定义媒体播放器

用媒体元素的play和pause方法可以手工控制媒体文件的播放,例子如下:

<div class="mediaplayer">      
<div class="video">         
<video id="player" src="movie.mov" poster="mymovie.jpg"  
width="300" height="200">             
Video player not available.         
</video>     
</div>     
<div class="controls">         
<input type="button" value="Play" id="video-btn">         
<span id="curtime">0</span>
<span id="duration">0</span>     
</div> 
</div> 

js代码如下

//取得元素的引用 
var player = document.getElementById("player"),     
btn = document.getElementById("video-btn"),     
curtime = document.getElementById("curtime"),     
duration = document.getElementById("duration"); 

//更新播放时间 
duration.innerHTML = player.duration; 

//为按钮添加事件处理程序 
EventUtil.addHandler(btn, "click", function(event){     
if (player.paused){         
player.play();         
btn.value = "Pause";     
} else {         
player.pause();         
btn.value = "Play";     
} }); 

//定时更新当前时间 
setInterval(function(){     
curtime.innerHTML = player.currentTime; 
}, 250);

3.4 检测编解码器的支持情况

用媒体元素的canPlayType()方法检测 该方法接受一种格式/编解码器字符串,返回probably,maybe或空字符串,例子如下:

var audio = document.getElementById("audio-player"); 

//很可能"maybe" 
if (audio.canPlayType("audio/mpeg"))
{     
//进一步处理 
} 

//可能是"probably" 
if (audio.canPlayType("audio/ogg; codecs=\"vorbis\""))
{     
//进一步处理 
}

以下是已知得到支持的音频格式或视频格式

3.5 Audio类型

<audio>元素有一个原生的js构造函数Audio,可以在任何时候播放音频,例子如下:

var audio = new Audio("sound.mp3"); 
EventUtil.addHandler(audio, "canplaythrough", 
function(event){     
audio.play(); 
});

4. 历史状态管理

通过hashchange事件,可以知道URL参数在什么时候发生了变化 用history.pushState()方法改变浏览器的URL,接受三个参数:状态对象,新状态标题,可选的URL,例如:

history.pushState({name:"Nicholas"}, "Nicholas' page", "nicholas.html");

使用这个方法后,新的状态信息就会被加入历史状态栈,浏览器地址就会变成新的URL,不过浏览器不会发出请求,查询location.href会返回与地址栏相同的地址。 这时按下后退键,则会触发window对象的popstate事件,事件对象有一个state属性,这个属性包含当初以第一个参数传递给pushState()的状态对象。 代码如下:

EventUtil.addHandler(window, "popstate", function(event){  var state = event.state;     
if (state){   
//第一个页面加载时 state 为空         
processState(state);     
} });

得到状态对象后,必须把页面重置为状态对象的数据表示的状态,第一个页面没有状态,event.state的值为null 若要更新当前状态,可以调用replaceState()方法,传入参数与pushState的前两个参数相同,调用这个方法不会在历史状态栈中创建新状态,只会改变当前状态