文章来源:小青年原创
发布时间:2016-05-29
关键词:mui,html5+,XMLHttpRequest,ajax,懒加载
转载需标注本文原始地址: http://zhaomenghuan.github.io...javascript
这是这个系列的的第三篇文章,前面的文章在多个地方(本人github
博客、dcloud ask
社区、segmentfault
)发出来了,不少朋友收藏点赞,只是没有多少人反映内容的深浅,也没有人提出意见,因此实话说不知道符不符合你们胃口,不过我写博客一贯以详细为标准,尽量照顾到各类人群,特别是入门级的同窗,力求还原我学习这个东西的一个思路和过程,在文章中也分享一些不错的干货,最近在折腾博客,用webpack
和vue-cli
打包了一下,目前还有些问题有待解决,本身尝试写一个markdown编辑器由于bug过多的问题,而后开始使用马克飞象写博客,毕竟生成的界面美观多了,这样能够方便你们阅读吧。废话很少说,开始咱们今天的内容,今天主要是学习一下html5+
的XMLHttpRequest
以及mui
的基本用法。php
XMLHttpRequest 是一个 JavaScript 对象,它最初由微软设计,随后被 Mozilla、Apple 和 Google采纳. 现在,该对象已经被 W3C组织标准化. 经过它,你能够很容易的取回一个URL上的资源数据. 尽管名字里有XML, 但 XMLHttpRequest 能够取回全部类型的数据资源,并不局限于XML。 并且除了HTTP ,它还支持file 和 ftp 协议. —— MDN XMLHttpRequestcss
XMLHttpRequest
让发送一个HTTP
请求变得很是容易。你只须要简单的建立一个请求对象实例,打开一个URL
,而后发送这个请求。当传输完毕后,结果的HTTP
状态以及返回的响应内容也能够从请求对象中获取。html
第一步:建立一个 XMLHttpRequest 实例前端
new XMLHttpRequest();
第二步:初始化HTTP请求参数vue
void open( DOMString method, DOMString url, optional boolean async, optional DOMString user, optional DOMString password );
method:请求所使用的HTTP
方法; 例如 "GET"
, "POST"
, "PUT"
, "DELETE"
等. 若是下个参数是非HTTP(S)
的URL
,则忽略该参数.html5
url:该请求所要访问的URL
java
async:一个可选的布尔值参数,默认为true
,意味着是否执行异步操做,若是值为false
,则send()
方法不会返回任何东西,直到接受到了服务器的返回数据。若是为值为true
,一个对开发者透明的通知会发送到相关的事件监听者。这个值必须是true
,若是multipart
属性是true
,不然将会出现一个意外。node
user:用户名,可选参数,为受权使用;默认参数为空string
.jquery
password:密码,可选参数,为受权使用;默认参数为空string
.
第三步:发送请求
send();
发送请求. 若是该请求是异步模式(默认),该方法会马上返回. 相反,若是请求是同步模式,则直到请求的响应彻底接受之后,该方法才会返回.
以下例:
var xhr = new XMLHttpRequest(); xhr.onload = function () { console.log(this.responseText); }; xhr.onreadystatechange = function() { console.log(this.readyState); }; xhr.open("get", "https://www.baidu.com", true); xhr.send();
咱们在hbuilder里面打开,控制台会报错:
[Web浏览器] "XMLHttpRequest cannot load https://www.baidu.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8020' is therefore not allowed access."
用浏览器打开,按F12
在控制台console
下查看也会发现上述错误,这是为啥呢?
这是由于普通网页可以使用XMLHttpRequest
对象发送或者接受服务器数据, 可是它们受限于同源策略。只要先获取了跨域请求许可,就能够进行跨域请求。
同源策略:若是两个页面的协议、域名和端口是彻底相同的,那么它们就是同源的。同源策略是为了防止从一个地址加载的文档或脚本访问或者设置从另一个地址加载的文档的属性。若是两个页面的主域名相同,则还能够经过设置
document.domain
属性将它们认为是同源的。
CORS 的全称是 Cross-Origin Resource Sharing,即跨域资源共享。他的原理就是使用自定义的 HTTP 头部,让服务器与浏览器进行沟通,主要是经过设置响应头的 Access-Control-Allow-Origin 来达到目的的。这样,XMLHttpRequest 就能跨域了。想要进一步了解CORS的朋友能够看看这篇文章:了解跨域资源共享 (CORS)
在服务器端添加响应头Access-Control-Allow-Origin
,使用XMLHttpRequest
对象请求。值得注意的是,正常状况下的 XMLHttpRequest 是只发送一次请求的,可是跨域问题下极可能是会发送两次的请求(预发送)。
PHP:
header('Access-Control-Allow-Origin: *');
java:
response.addHeader( "Access-Control-Allow-Origin", "*" );
你们不妨将上面那个例子中的地址换成这个试试:http://zhaomenghuan.github.io...
(仅用于学习测试,禁止直接用于任何不经征求本人赞成的站点)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script type="text/javascript"> var xhr = new XMLHttpRequest(); xhr.open("get", "http://zhaomenghuan.github.io/api/blog.json", true); xhr.onload = function () { console.log(this.responseText); var data = JSON.parse(this.responseText); for(var i in data){ document.write(data[i].pageId + ':' + data[i].title+"<br />") } }; xhr.onerror = function () { alert('error making the request.'); }; xhr.send(); </script> </body> </html>
哈哈,执行完这段代码你会发现,你可以查看到我博客的列表,因此你们是否是懂了些什么, CORS可否跨域实现须要服务器端支持,咱们这里可以收到信息,是由于github上的资源是支持CORS访问的,这和框架无关,不少人觉得用了框架就能够跨域,这都是不正确的理解,框架只是封装了一些方法,让咱们使用更加方便,能不能跨域仍是取决于咱们服务器端的访问权限。这里顺便说一下不少人用mui会发如今浏览器端会报错,在app环境可以访问,这是由于mui依赖html5+ XMLHttpRequest网络请求模块,后面会详细讲到。
Jsonp
的跨域不是用XMLHttpRequest
实现的,而是一个script
标签,script
是能够跨域的,回调函数做为get
参数传入请求里。
原理很简单,好比你在A域名请求B域名:
在A域名的页面中使用script标签src写成B域名中服务器的URLscript标签是能够跨域的,好比你调用Google Map或Google Analytics时引入的js就是google域名下的。
后端程序在最后须要把一段js代码的字符串打印出来,这样就能够运行A域名js中写好的callback方法,将要返回的数据放入参数就能够了
A域名中的js文件:
function CreateScript(src){ var el = document.createElement('script'); el.src = src; el.async = true; el.defer = true; document.body.appendChild(el); } // 响应的方法 function jsonpcallback(rs) { console.log(JSON.stringify(rs)); document.getElementById("output").innerHTML = JSON.stringify(rs); } // 发起get请求 CreateScript('http://127.0.0.1:8888?userid=001&callback=jsonpcallback');
B域名中node服务器:
var http = require('http'); var url = require('url'); var data = { 'name': 'zhaomenghuan', 'age': '22' }; http.createServer(function(req, res){ // 将url字符串转换成Url对象 var params = url.parse(req.url, true); console.log(params); // 查询参数 if(params.query){ // 根据附件条件查询 if(params.query.userid === '001'){ // 判断是否为jsonp方式请求,如果则使用jsonp方式,不然为普通web方式 if (params.query.callback) { var resurlt = params.query.callback + '(' + JSON.stringify(data) + ')'; res.end(resurlt); } else { res.end(JSON.stringify(data)); } } } }).listen(8888);
这样咱们就能够在A域名下跨域请求,固然咱们常常看到不少框架如jquery对jsonp进行了进一步封装,可是基本原理同上面。这里给出两个例子:
总之,不管是XMLHttpRequest
的跨域,仍是Jsonp
,都是须要请求的网站服务器端提供支持,在愿意分享给你数据的状况下你才能获得。在对方没有提供支持的状况下,你是取不到它的数据的。固然跨域的解决方案有不少种,因为本人没有实践过,没有实践就没有发言权,这里给你们贴一个帖子,本身跨域自行验证,浅谈浏览器端JavaScript跨域解决方法。
上面咱们花了很大篇幅讲解了JavaScript XMLHttpRequest
对象,并且也简单的讲解了同源策略和跨域请求的经常使用方法,咱们注意到不管是JavaScript XMLHttpRequest
仍是jsonp
都须要经过服务器端的支持才能实现跨域,另外还有几种也有必定的局限性,因此总仍是让人以为美中不足。html5+
提供了一个XMLHttpRequest
模块,在APP
端很完美的解决了这种问题,并且提供了和JavaScript XMLHttpRequest
对象用法相似的一系列属性方法。因为本文的重在在于讲解html5+ XMLHttpRequest
,因此前面的JavaScript XMLHttpRequest
相关的属性方法只是初略介绍了一下,下面重点介绍html5+ XMLHttpRequest
模块。
因为html5+ XMLHttpRequest
是一种拓展方案,因此须要底层支持,基于html5+ XMLHttpRequest
的方法不能用于非5+
环境,若是对这些概念不清楚的欢迎先阅读我以前写的文章mui初级入门教程(一)— 菜鸟入手mui的学习路线。
咱们用hbuilder
新建一个app工程,而后运行下面的代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title></title> </head> <body> <script type="text/javascript"> document.addEventListener('plusready', function(){ var xhr = new plus.net.XMLHttpRequest(); xhr.onreadystatechange = function () { switch ( xhr.readyState ) { case 0: console.log( "xhr请求已初始化" ); break; case 1: console.log( "xhr请求已打开" ); break; case 2: console.log( "xhr请求已发送" ); break; case 3: console.log( "xhr请求已响应"); break; case 4: if ( xhr.status == 200 ) { alert( "xhr请求成功:"+xhr.responseText ); } else { console.log( "xhr请求失败:"+xhr.readyState ); } break; default : break; } } xhr.open("GET", "https://www.baidu.com/"); xhr.send(); }, false ); </script> </body> </html>
咱们会发现最后弹出了弹框,里面写有百度首页的代码。
建立一个XMLHttpRequest
对象,对象建立时不触发任什么时候间和网络请求,需和open
,send
方法配合使用。
var xhr = new plus.net.XMLHttpRequest(); xhr.open(method, url); xhr.send();
XMLHttpRequest的属性:
readyState: HTTP 请求的状态
response: 请求从服务器接收到的响应数据
responseText: 请求从服务器接收到的响应数据(字符串数据)
responseType:请求响应数据response的类型
responseXML: 请求响应的Document对象
status: 服务器返回的HTTP状态代码
statusText: 服务器返回的HTTP状态描述
timeout: 请求服务器的超时时间,单位为毫秒(ms)
withCredentials: 是否支持跨域请求
XMLHttpRequest的方法:
abort: 取消当前响应,关闭链接而且结束任何未决的网络活动
getAllResponseHeaders: 获取HTTP响应头部信息
getResponseHeader: 获取指定的HTTP响应头部的值
open: 初始化HTTP请求参数,例如URL和HTTP方法,可是并不发送请求
send: 发送HTTP请求
setRequestHeader: 指定一个HTTP请求的Header
XMLHttpRequest的事件:
onreadystatechange: 网络请求状态发生变化事件
onloadstart: 网络请求开始事件
onprogress: 网络请求传输数据事件
onabort: 网络请求取消事件
onerror: 网络请求错误事件
onload: 网络请求成功事件
ontimeout: 网络请求超时事件
onloadend: 网络请求结束事件
mui
框架基于htm5plus
的XMLHttpRequest
,封装了经常使用的Ajax
函数,支持GET
、POST
请求方式,支持返回json
、xml
、html
、text
、script
数据类型; 本着极简的设计原则,mui
提供了mui.ajax
方法,并在mui.ajax
方法基础上,进一步简化出最经常使用的mui.get()
、mui.getJSON()
、mui.post()
三个方法。
mui.ajax( url [,settings] )
url:请求发送的目标地址
settings:key/value格式的json对象,用来配置ajax请求参数,支持的参数以下:
data:发送到服务器的业务数据;
type:请求方式,目前仅支持'GET'和'POST',默认为'GET'方式;
dataType:预期服务器返回的数据类型;若是不指定,mui将自动根据HTTP包的MIME头信息自动判断;
支持设置的dataType可选值:
"xml": 返回XML文档
"html": 返回纯文本HTML信息;
"script": 返回纯文本JavaScript代码
"json": 返回JSON数据
"text": 返回纯文本字符串
success:Type: Functon(Anything data,String textStatus,XMLHttpRequest xhr)
请求成功时触发的回调函数,该函数接收三个参数:
data:服务器返回的响应数据,类型能够是json对象、xml对象、字符串等;
textStatus:状态描述,默认值为'success'
xhr:xhr实例对象
error:Type: Functon(XMLHttpRequest xhr,String type,String errorThrown)请求失败时触发的回调函数;
该函数接收三个参数:
- xhr:xhr实例对象
- type:错误描述,可取值:"timeout", "error", "abort", "parsererror"、"null" - errorThrown:可捕获的异常对象
timeout:Type: Number,请求超时时间(毫秒),默认值为0,表示永不超时;若超过设置的超时时间(非0的状况),依然未收到服务器响应,则触发error回调;
headers:Type: Object,格式为:{'Content-Type':'application/json'}
,
详情参考html5+ setRequestHeader。
基本格式以下:
mui.ajax(url,{
data:{
username:'username', password:'password' }, dataType:'json',//服务器返回json格式数据 type:'post',//HTTP请求类型 timeout:10000,//超时时间设置为10秒; success:function(data){ //服务器返回响应,根据响应结果,分析是否登陆成功; ... }, error:function(xhr,type,errorThrown){ //异常处理; console.log(type); } });
mui.post( url [,data] [,success] [,dataType] )
mui.post()
方法是对mui.ajax()
的一个简化方法,直接使用POST
请求方式向服务器发送数据、且不处理timeout
和异常(若需处理异常及超时,请使用mui.ajax()
方法)
mui.post('http://server-name/login.php',{ username:'username', password:'password' },function(data){ //服务器返回响应,根据响应结果,分析是否登陆成功; ... },'json' );
mui.get( url [,data] [,success] [,dataType] )
mui.get()
方法和mui.post()
方法相似,只不过是直接使用GET
请求方式向服务器发送数据、且不处理timeout
和异常(若需处理异常及超时,请使用mui.ajax()
方法)。以下为得到某服务器新闻列表的代码片断,服务器以json格式返回数据列表:
mui.get('http://server-name/list.php', {category:'news'}, function(data){ //得到服务器响应 ... },'json' );
mui.get( url [,data] [,success] )
mui.getJSON()
方法是在mui.get()
方法基础上的更进一步简化,限定返回json
格式的数据,其它参数和mui.get()
方法一致,如上得到新闻列表的代码换成mui.getJSON()
方法后,更为简洁,以下:
mui.getJSON('http://server-name/list.php', {category:'news'}, function(data){ //得到服务器响应 ... } );
mui在getJSON基础上封装了一个jsonp插件,具体dem能够参考这里:mui-jsonp实现有道词典翻译
注:初学者肯对于GET与POST的区别不是很清楚,这里不作详细介绍,若要深刻了解请查看:GET,POST — 简述
咱们接着上一篇文章的项目开始进行本节的内容,上一篇咱们讲解了html5+ webview
的使用方法,而且实现了一个基于父子webview
的tab bar
切换的案例,咱们此次利用网易音乐API
接口请求数据,完成咱们后续的音乐播放器功能。
网易音乐搜索API:
type:"GET"或“POST" //HTTP请求类型
请求参数:
type: 1
s: //关键词
limit: 10 //限制返回结果数为10
offset: 0 //偏移
src: lofter //可为空
filterDj: true | false //可为空
callback: //为空时返回json,反之返回jsonp callback
因为HTTP请求类型包含get,咱们只须要把请求的参数拼接到url里面就能够获得返回的数据,格式为url?key1=value1&key2=value2。
在这个例子中咱们打开这个网址http://s.music.163.com/search...,咱们会发现一些数据返回了,以下图:
OK,咱们下面讲解怎么经过程序获得这些数据,而且咱们而且怎么解析这些数据。
在开始以前咱们先对咱们要获得的数据进行美化,这里我在网上随便搜了一个
在线JSON校验格式化工具,咱们只须要把刚刚那些数据复制粘贴到我给的这个工具里面,而后点击校验就变整齐了。
{
"result": { "songCount": 3224, "songs": [ { "id": 28949444, "name": "喜欢你", "artists": [ { "id": 7763, "name": "G.E.M.邓紫棋", "picUrl": null } ], "album": { "id": 2956076, "name": "喜欢你", "artist": { "id": 0, "name": "", "picUrl": null }, "picUrl": "http://p1.music.126.net/u_1EudmF8Swgow6vfgYe1g==/8896148580676276.jpg" }, "audio": "http://m2.music.126.net/_icR1apQHVl8wa0EP_REkQ==/3269947581061892.mp3", "djProgramId": 0 } ] }, "code": 200 }
咱们能够看到
"picUrl":"http://p1.music.126.net/u_1EudmF8Swgow6vfgYe1g==/8896148580676276.jpg"
打开这个图片地址咱们就能够看到邓紫棋了,哈哈,也就是说咱们只须要抓取到这个地址就能够进行下面的工做咯,其余的相似。
咱们在上次新建的M-BOX下的home.html下写这个例子:
<script src="../js/mui.min.js"></script> <script type="text/javascript"> var url = "http://s.music.163.com/search/get/"; mui.ajax(url,{ data: { 'type': 1, 's': "喜欢你", 'limit': 10 }, dataType:'json',//服务器返回json格式数据 type:'post',//HTTP请求类型 timeout:10000,//超时时间设置为10秒; success:function(data){ console.log(JSON.stringify(data)); }, error:function(xhr,type,errorThrown){ //异常处理; console.log(type); } }); </script>
hbuilder
很方便的一个功能就是真机调试,咱们直接将电脑与手机链接,经过console.log()
函数能够很方便的将数据在控制台打印出来,例如上述例子若是咱们在success
的回调函数中执行console.log(data);
,在控制台会输出[object Object]
,咱们只须要利用JSON.stringify()
方法能够将任意的 JavaScript
值序列化成 JSON
字符串。
每次看到不少同窗在解析json
的时候错误百出,严重暴漏了基本功,这里我就总结几条与解析json
可能相关的知识点。
JSON: JavaScript Object Notation
(JavaScript 对象表示法),JSON
是存储和交换文本信息的语法,独立于语言。相似 XML
。JSON
比 XML
更小、更快,更易解析,具备自我描述性,更易理解的特色。
JSON
就是一串字符串,只不过元素会使用特定的符号标注。
{} 双括号表示对象
[] 中括号表示数组
"" 双引号内是属性或值
:表示后者是前者的值(这个值能够是字符串、数字、也能够是另外一个数组或对象)
{"name": "Dcloud"}
能够理解为是一个包含name
为Dcloud
的对象;[{"name": "mui"},{"name": "html5+"}]
就表示包含两个对象的数组。
经过JavaScript
,您能够建立一个对象数组,并像这样进行赋值:
var employees = [ { "firstName":"John" , "lastName":"Doe" }, { "firstName":"Anna" , "lastName":"Smith" }, { "firstName":"Peter" , "lastName": "Jones" } ];
能够像这样访问 JavaScript 对象数组中的第一项:employees[0].lastName;
返回的内容是:Doe
能够像这样修改数据:employees[0].firstName = "Jonatan";
这里须要特别说明的是两个很是有用的方法:JSON.stringify和JSON.parse。咱们能够经过JSON.stringify将json对象转成json字符串,方便用alert,console.log打印出来,能够方便的查看json对象内容。反之咱们能够经过JSON.parse将json字符串转成json对象以即可以方便对json对象取值。例:
// 场景1 var data = { name: 'zhaomenghuan', age: 22 } console.log(typeof data); // "object" console.log(JSON.stringify(data)) // "{"name":"zhaomenghuan","age":22}" // 场景2 var str = '{"name":"zhaomenghuan","age":22}'; console.log(typeof str) // "string" console.log(JSON.parse(str).name) // "zhaomenghuan"
上面的例子列举了两种应用场景,你们根据本身的状况合适的选取正确的方法。
[ ]能够用于数组和对象取值,数组中按下边取值。
var array=["one","two","three","four"]; array[0];
对象属性取值时,当咱们不知道属性名或属性名自己包含点(.)的键,应当使用[ ]。
for(var key in obj){ console.log(key + ":" + obj[key]); }
var obj={ id:"obj", "self.ref":ref } console.log(obj["self.ref"]);
.运算符的左边为一个对象,右边为属性名。如:obj.id
var key="property"; console.log(key); var obj={ property:"hello word" } console.log(obj[key]);
var array=[1,2,3,4,5]; array.map(function(item){ return item*2; });
数组map
方法能够接受一个匿名函数,数组中每一个元素都会调用这个匿名函数,而且讲返回结果放在一个数组中。
mui
中的each()
方法既是一个类方法,同时也是一个对象方法,两个方法适用场景不一样;换言之,你可使用mui.each()
去遍历数组或json
对象,也可使用mui(selector).each()
去遍历DOM
结构。
mui.each( obj , handler )
obj :Type: Array||JSONObj
需遍历的对象或数组;若为对象,仅遍历对象根节点下的key
handler :Type: Function( Integer||String index,Anything element)
为每一个元素执行的回调函数;其中,index表示当前元素的下标或key,element表示当前匹配元素
对于前面说到的音乐api
返回的json
数据,首先咱们要经过var songs=data.result.songs;
获取"songs"
的值,而后遍历"songs"
对象的子对象。
···
success:function(data){ // console.log(JSON.stringify(data)); var songs=data.result.songs; mui.each(songs,function(index,item){ var id = item.id, name = item.album.name, author = item.artists[0].name, picUrl = item.album.picUrl, audio = item.audio; }) }, ···
咱们用上述代码能够获得咱们想要的数据,下面就是须要将信息展现出来,这里咱们只获取 歌曲id
、歌曲所属专辑名name
、歌曲第一做者author
、歌曲所属专辑图片picUrl
、歌曲音频文件audio
。
考虑到要加载不少图片,这里咱们使用懒加载实现效果,这里咱们直接使用hello mui
里面的模板页面lazyload-image.html
,咱们须要引入mui.lazyload.js
和mui.lazyload.img.js
两个文件,还有占位图。下面先贴出修改后的基本的代码,而后再讲解其中的内容。
home.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>M-BOX</title> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <!--标准mui.css--> <link rel="stylesheet" href="../css/mui.min.css"> <style type="text/css"> .mui-content>.mui-table-view:first-child { margin-top: 0px; } </style> </head> <body> <div class="mui-content"> <ul id="list" class="mui-table-view mui-table-view-chevron"></ul> </div> </body> <script src="../js/mui.min.js "></script> <script src="../js/mui.lazyload.js"></script> <script src="../js/mui.lazyload.img.js"></script> <script> mui.init(); var url = "http://s.music.163.com/search/get/"; mui.ajax(url,{ data: { 'type': 1, 's': "喜欢你", 'limit': 10 }, dataType:'json',//服务器返回json格式数据 type:'post',//HTTP请求类型 timeout:10000,//超时时间设置为10秒; success:function(data){ //console.log(JSON.stringify(data)); var songs=data.result.songs; var list = document.getElementById("list"); var fragment = document.createDocumentFragment(); var li; mui.each(songs,function(index,item){ var id = item.id, name = item.album.name, author = item.artists[0].name, picUrl = item.album.picUrl, audio = item.audio; li = document.createElement('li'); li.className = 'mui-table-view-cell mui-media'; li.innerHTML = '<a class="mui-navigate-right" id='+ id +' data-audio='+ audio +'>'+ '<img class="mui-media-object mui-pull-left" data-lazyload="'+picUrl+'">'+ '<div class="mui-media-body">'+name+ '<p class="mui-ellipsis">'+author+'</p>'+ '</div>'+ '</a>'; fragment.appendChild(li); }) list.appendChild(fragment) mui(document).imageLazyload({ placeholder: '../img/60x60.gif' }); }, error:function(xhr,type,errorThrown){ //异常处理; console.log(type); } }); //列表点击事件 mui("#list").on('tap','li a',function(){ var id = this.getAttribute('id'); var audio = this.getAttribute('data-audio'); //打开详情页面 mui.openWindow({ url:'music.html', id:'music.html', extras:{ musicId:id, audioUrl:audio } }); }); </script> </html>
music.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title></title> <link href="../css/mui.min.css" rel="stylesheet"/> </head> <body> <script src="../js/mui.min.js"></script> <script type="text/javascript"> mui.init(); mui.plusReady(function(){ var self = plus.webview.currentWebview(); var musicId = self.musicId; var audioUrl = self.audioUrl; document.write("musicId:" + musicId + "<br />"); document.write("audioUrl:" + audioUrl); }); </script> </body> </html>
咱们这里说几个开发者常见的问题:
首先打开hello mui
里面的模板页面lazyload-image.html
,咱们打开控制台查看elements
,结构以下:
<ul id="list" class="mui-table-view mui-table-view-chevron"> <li class="mui-table-view-cell mui-media"> <a class="mui-navigate-right"> <img class="mui-media-object mui-pull-left" data-lazyload-id="0" src="http://www.dcloud.io/hellomui/images/1.jpg?version=447.4190210457891"> <div class="mui-media-body"> 主标题 <p class="mui-ellipsis">列表二级标题</p> </div> </a> </li> </ul>
咱们须要将获取的内容动态的填充到这个里面,这里经常使用的方法就是动态的生成节点,这里咱们就要用到DOM
的建立方法document.createElement
,经过这个方法咱们能够生成一个节点: li = document.createElement('li');
这个能够生成一个li
节点,咱们须要为这个li
指定class
,经过对对象的className
赋值实现,如:li.className = 'mui-table-view-cell mui-media';
,咱们使用appendChild(li)
方法将li
节点挂着父节点上,好比:
var list = document.getElementById("list"); list.appendChild(li);
这个就是把li
节点挂在list
下,同理咱们能够在li
节点下 建立子节点,上面为了简单,咱们使用给innerHTML
属性赋值的作法,这样innerHTML
的值一样会挂在li
节点下,你们须要注意的是innerHTML
属性的值我字符串,因此咱们往中间插入了变量,要使用+
链接起来。咱们能够经过循环建立多个节点,以下面这样建立十个段落:
for(var i = 0 ; i < 10; i ++) { var p = document.createElement("p"); var oTxt = document.createTextNode("段落" + i); p.appendChild(oTxt); document.body.appendChild(p); }
上面咱们使用的是mui.each()
方法,效果相似。
若是细心的同窗或许注意到咱们使用了一个奇怪的写法:
var fragment = document.createDocumentFragment(); mui.each(songs,function(index,item){ ... fragment.appendChild(li); }); list.appendChild(fragment);
为啥咱们要在这里使用document.createDocumentFragment()
呢?
若是是对前端技术感兴趣的同窗说不定回去查一下,我相信大部分人可能就放过了吧!这里我查了一下资料:
在《javascript高级程序设计》一书的6.3.5:建立和操做节点一节中,介绍了几种动态建立html节点的方法,其中有如下几种常见方法:
crateAttribute(name): 用指定名称name建立特性节点
createComment(text): 建立带文本text的注释节点
createDocumentFragment(): 建立文档碎片节点
createElement(tagname): 建立标签名为tagname的节点
createTextNode(text): 建立包含文本text的文本节点
其中最感兴趣且之前没有接触过的一个方法是createDocumentFragment()方法,书中介绍说:在更新少许节点的时候能够直接向document.body节点中添加,可是当要向document中添加大量数据是,若是直接添加这些新节点,这个过程很是缓慢,由于每添加一个节点都会调用父节点的appendChild()方法,为了解决这个问题,能够建立一个文档碎片,把全部的新节点附加其上,而后把文档碎片一次性添加到document中。—— document的createDocumentFragment()方法
咱们点击了列表,咱们会进入一个详情页,咱们确定是想知道咱们究竟点了哪个咱们想把一些数据传入到详情页面,这里咱们使用了mui.openWindow()
方法中的拓展参数extras
传入几个值,在详情页面经过plus.webview.currentWebview
获取:
mui.plusReady(function(){ var self = plus.webview.currentWebview(); var musicId = self.musicId; var audioUrl = self.audioUrl; document.write("musicId:" + musicId + "<br />"); document.write("audioUrl:" + audioUrl); });
这是在页面初始化时,经过扩展参数extras
传值;另外还有页面已建立,经过自定义事件传值,参考mui官网中自定义事件的介绍,这里先不讲得太多,后面会专门花时间详细讲解相关细节。
因为前面已经详细讲解,这里就再也不赘述,只给出一个基本的demo:jsonp获取网易云音乐。
当咱们写到这里,发现这篇依然是长长的一篇干货,不少内容摘自文档,主要是为了新手能够详细去了解整个流程。其实还有不少没有写出来,限于篇幅仍是后面再写吧!因为代码在文章中写得很详细,工程代码先不给出来,最后整个系列写完了再放出来吧!
这段时间在技术上花得时间确实太多,刚刚和女友在图书馆学习,她和我开个玩笑,我在忙着作做业由于不喜欢被打扰,而后就以为很烦躁,而后就聊着聊着她说和我分手,我不知道她是否是认真的,只是以为空空的,自从走上代码这条路,我已经失去太多东西,我不想失去女友,毕竟谈了三年,我是真的爱她,写完这个就去找她道歉吧!还有要向环头道歉,昨天可能说话有点直接,不当心伤到他了,后来想一想真的多是我太较真,他只是想玩玩程序,我何须那种执着呢?若是环头看到这篇博客,但愿你能够原谅哥,我只是不想让你走弯路,或许每一个都应该本身去把握本身的人生,咱们没必要去干涉。