HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

Deferred long-running timer task(s)...

Deferred long-running timer task(s) to improve scrolling smoothness. See crbug.com/574343

Deferred long-running timer task(s) to improve scrolling smoothness. See crbug.com/574343

Mui前端架子(编程规范分享)

mui

原文标题:PHP Lumen - 入门教程 - web前端架子
转来自我的博客:http://blog.csdn.net/wowkk/article/details/52254696

用了Lumen一段时间了,感觉还不错。也适合全栈开发。因为我一丢丢PHP基础都没看就直接用起了框架,挺多地方还是闹笑话了。比如,字符串追加,PHP它喵的居然是用 “.” 来追加,而通过“->”进行属性调用也是不爽~

这个web前端架子,不是Lumen专用的,额外分享。

首先我写了一个公共类(common.js),主要用来进行封装请求的。

/*!  
 * =====================================================  
 * 全局通用变量  
 * =====================================================  
 */  
var Common = {};  
//Common.ServerUrl = "http://120.24.xx.xx:8080/";       //线上测试版本  
Common.ServerUrl = "http://192.168.0.110:8080/";    //公司测试版本  
//Common.ServerUrl = "http://192.168.99.139:8080/";     //宿舍测试版本  

Common.Post = function(url,data,successcallback,errcallback){  
    console.log(Common.jsonToUrl(url,data));  
    if(errcallback==null){  
        errcallback = function(xhr,type,errorThrown){  
            console.log(JSON.stringify(xhr))  
            plus.nativeUI.closeWaiting();//关闭旋转菊花  
            alert("网络异常:" + url);  
        }  
    }  
    //这里的mui是HBuilder跨平台开发工具自己的js,根据自己项目调改。  
    mui.ajax(Common.ServerUrl + url,{  
        data:data,  
        dataType:'json',  
        type:'post',  
        timeout:5000,  
        success:successcallback,  
        error:errcallback  
    });  
}  

Common.jsonToUrl=function(url,jsonData){  
    var full_url = Common.ServerUrl + url + "?";  
    for(var index in jsonData){  
        full_url = full_url + index + "=" + jsonData[index] + "&";  
    }  
    return full_url;  
};

可以把这段代码塞到js插件里面去(比如jQuery)减少请求。
这一丢丢代码有几个好处:
1.统一请求的url,不需要每个页面都去设置请求地址。页面发送ajax时,只需要把相对路径传进来就行了。
2.统一错误返回的处理,可以即时知道哪个请求出错。也可以根据需要特殊回调处理。
3.把post的data转换为url地址,方便直接复制到浏览器进行get调试。
4.方便拓展与维护,比如可以统一处理“未登录则自动跳转到登录页”。

再看下html页的代码

<script>  
        /*  
         * 页面配置  
         */  
        var PAGE = {  
                View: {},  
                page: 0,  
                Model: {  
                    Article: function(article) {  
                        return '<article id="' + article.information_id + '">' +  
                            '<div class="article-time">' +  
                            '<span>' + article.time_title + '</span>' +  
                            '</div>' +  
                            '<div class="article-bg" style="background-image: url(' + article.information_imgurl + ');">' +  
                            '<div class="article-bg-cover">' +  
                            '<span class="information_title"># ' + article.information_title + '</span>' +  
                            '</div>' +  
                            '</div>' +  
                            '<div class="mui-pull-right article_collect">' +  
                            '<img style="width: 100%;" src="../../img/news_shoucang.png" />' +  
                            '<div class="article_collect_fone">' + article.favour_num + '</div>' +  
                            '</div>' +  
                            '</article>';  
                    },  
                    Articles:function(articles){  
                        var html = "";  
                        for(var i = 0; i < articles.length; i++) {  
                            html += PAGE.Model.Article(articles[i]);  
                        }  
                        return html;  
                    }  
                }  
            };  
        mui.init();//(mui框架需要)初始化框架  
        mui.plusReady(function() {  
            PAGE.Init();//初始化本页面  
        });  
        /*  
         * 页面初始化  
         */  
        PAGE.Init = function() {  
                PAGE.preloadView();  
                PAGE.addEventListener();  
            }  
            /*  
             * 页面预加载  
             */  
        PAGE.preloadView = function() {}  
            /*  
             * 事件监听  
             */  
        PAGE.addEventListener = function() {  
            PAGE.addEventListener_Article();//确定监听点击文章列表的元素  
        }  
            /*  
             * 页面预加载-实现  
             */  
        PAGE.preloadView_Name = function() {}  
            /*  
             * 事件监听-实现  
             */  
        PAGE.addEventListener_Article = function() {  
                mui("#div_newList").on("tap", "article", function() {  
                    mui.openWindow({  
                        id: "/View/News/details.html",  
                        url: "/View/News/details.html",  
                        extras: {  
                            information_id: this.id,  
                            information_title: this.getElementsByClassName("information_title")[0].innerText,  
                            information_imgurl: this.getElementsByClassName("article-bg")[0].style.backgroundImage  
                        }  
                    })  
                })  
            }  
            /*  
             * 事件实现  
             */  
        PAGE.Event_Name = function() {}  
    </script>

编出来的这段,个人用起来还是比较舒服的。
1.所有js代码都是在PAGE这个域里面,尽量避免污染。
2.将所有监听事件独个封装起来,然后由PAGE.addEventListener统一调用。这样在简单事件较多的情况下,代码也足够清晰易阅读和定位。
3.所有动态生成的代码放在PAGE.Model对象里面(传人json数据,返回对应的html代码)。同样也是清晰易阅读和定位。
4.普通函数比如,更新页面数据就用PAGE.Event_XXX格式命名函数。这个主要就是统一规范吧。
5.一些配置变量,比如当前页PageNum,也可以防止PAGE里面去维护。

接下来继续实战,看能不能怎么优化。现在为了性能,大多数都是用原生js,看看有没有机会封装个js架子。

继续阅读 »

原文标题:PHP Lumen - 入门教程 - web前端架子
转来自我的博客:http://blog.csdn.net/wowkk/article/details/52254696

用了Lumen一段时间了,感觉还不错。也适合全栈开发。因为我一丢丢PHP基础都没看就直接用起了框架,挺多地方还是闹笑话了。比如,字符串追加,PHP它喵的居然是用 “.” 来追加,而通过“->”进行属性调用也是不爽~

这个web前端架子,不是Lumen专用的,额外分享。

首先我写了一个公共类(common.js),主要用来进行封装请求的。

/*!  
 * =====================================================  
 * 全局通用变量  
 * =====================================================  
 */  
var Common = {};  
//Common.ServerUrl = "http://120.24.xx.xx:8080/";       //线上测试版本  
Common.ServerUrl = "http://192.168.0.110:8080/";    //公司测试版本  
//Common.ServerUrl = "http://192.168.99.139:8080/";     //宿舍测试版本  

Common.Post = function(url,data,successcallback,errcallback){  
    console.log(Common.jsonToUrl(url,data));  
    if(errcallback==null){  
        errcallback = function(xhr,type,errorThrown){  
            console.log(JSON.stringify(xhr))  
            plus.nativeUI.closeWaiting();//关闭旋转菊花  
            alert("网络异常:" + url);  
        }  
    }  
    //这里的mui是HBuilder跨平台开发工具自己的js,根据自己项目调改。  
    mui.ajax(Common.ServerUrl + url,{  
        data:data,  
        dataType:'json',  
        type:'post',  
        timeout:5000,  
        success:successcallback,  
        error:errcallback  
    });  
}  

Common.jsonToUrl=function(url,jsonData){  
    var full_url = Common.ServerUrl + url + "?";  
    for(var index in jsonData){  
        full_url = full_url + index + "=" + jsonData[index] + "&";  
    }  
    return full_url;  
};

可以把这段代码塞到js插件里面去(比如jQuery)减少请求。
这一丢丢代码有几个好处:
1.统一请求的url,不需要每个页面都去设置请求地址。页面发送ajax时,只需要把相对路径传进来就行了。
2.统一错误返回的处理,可以即时知道哪个请求出错。也可以根据需要特殊回调处理。
3.把post的data转换为url地址,方便直接复制到浏览器进行get调试。
4.方便拓展与维护,比如可以统一处理“未登录则自动跳转到登录页”。

再看下html页的代码

<script>  
        /*  
         * 页面配置  
         */  
        var PAGE = {  
                View: {},  
                page: 0,  
                Model: {  
                    Article: function(article) {  
                        return '<article id="' + article.information_id + '">' +  
                            '<div class="article-time">' +  
                            '<span>' + article.time_title + '</span>' +  
                            '</div>' +  
                            '<div class="article-bg" style="background-image: url(' + article.information_imgurl + ');">' +  
                            '<div class="article-bg-cover">' +  
                            '<span class="information_title"># ' + article.information_title + '</span>' +  
                            '</div>' +  
                            '</div>' +  
                            '<div class="mui-pull-right article_collect">' +  
                            '<img style="width: 100%;" src="../../img/news_shoucang.png" />' +  
                            '<div class="article_collect_fone">' + article.favour_num + '</div>' +  
                            '</div>' +  
                            '</article>';  
                    },  
                    Articles:function(articles){  
                        var html = "";  
                        for(var i = 0; i < articles.length; i++) {  
                            html += PAGE.Model.Article(articles[i]);  
                        }  
                        return html;  
                    }  
                }  
            };  
        mui.init();//(mui框架需要)初始化框架  
        mui.plusReady(function() {  
            PAGE.Init();//初始化本页面  
        });  
        /*  
         * 页面初始化  
         */  
        PAGE.Init = function() {  
                PAGE.preloadView();  
                PAGE.addEventListener();  
            }  
            /*  
             * 页面预加载  
             */  
        PAGE.preloadView = function() {}  
            /*  
             * 事件监听  
             */  
        PAGE.addEventListener = function() {  
            PAGE.addEventListener_Article();//确定监听点击文章列表的元素  
        }  
            /*  
             * 页面预加载-实现  
             */  
        PAGE.preloadView_Name = function() {}  
            /*  
             * 事件监听-实现  
             */  
        PAGE.addEventListener_Article = function() {  
                mui("#div_newList").on("tap", "article", function() {  
                    mui.openWindow({  
                        id: "/View/News/details.html",  
                        url: "/View/News/details.html",  
                        extras: {  
                            information_id: this.id,  
                            information_title: this.getElementsByClassName("information_title")[0].innerText,  
                            information_imgurl: this.getElementsByClassName("article-bg")[0].style.backgroundImage  
                        }  
                    })  
                })  
            }  
            /*  
             * 事件实现  
             */  
        PAGE.Event_Name = function() {}  
    </script>

编出来的这段,个人用起来还是比较舒服的。
1.所有js代码都是在PAGE这个域里面,尽量避免污染。
2.将所有监听事件独个封装起来,然后由PAGE.addEventListener统一调用。这样在简单事件较多的情况下,代码也足够清晰易阅读和定位。
3.所有动态生成的代码放在PAGE.Model对象里面(传人json数据,返回对应的html代码)。同样也是清晰易阅读和定位。
4.普通函数比如,更新页面数据就用PAGE.Event_XXX格式命名函数。这个主要就是统一规范吧。
5.一些配置变量,比如当前页PageNum,也可以防止PAGE里面去维护。

接下来继续实战,看能不能怎么优化。现在为了性能,大多数都是用原生js,看看有没有机会封装个js架子。

收起阅读 »

底部选项卡被输入法撑起问题解决

输入法 选项卡

1.如果是单页面出现的问题,可以使用
mui.plusReady(function() {
//设置bottom绝对位置
document.getElementById('bottomx').style.top = (plus.display.resolutionHeight - 50) + "px";
});
这段代码 转自:解决弹出输入法时页面高度变小导致底部上浮的问题

2.如果选项卡在父页面中,并且在页面中的样式中设置了bottom属性,可以使用
mui.plusReady(function(){
var self=plus.webview.currentWebview();
/**

  • 防止 在write页面输入文字的时候 , 输入法把选项卡撑起来
    */
    var parentVebView =self.opener();
    //防止 父页面选项卡被输入法撑起
    window.addEventListener('resize', function() {
    var a=plus.android.invoke(plus.android.currentWebview(),"getHeight") ;
    var b=plus.navigator.getStatusbarHeight();
    var c=plus.screen.resolutionHeight ;
    var d=(c-a-b);
    console.info('webview高度:'+a+" 状态栏高度:"+b+" 屏幕高度:"+c+" 输入法高度:"+d)
    d >0 ? self.setStyle({top: '45px',bottom: '0px'}) : self.setStyle({top: '45px',bottom: '50px'});
    //d > 0 ? parentVebView.evalJS("mui('#nav_id').css('position','absolute');") : parentVebView.evalJS("mui('#nav_id').css('position','fixed');");
    }, false);
    });
    当输入法打开时 重新设置当前webview的 style属性
继续阅读 »

1.如果是单页面出现的问题,可以使用
mui.plusReady(function() {
//设置bottom绝对位置
document.getElementById('bottomx').style.top = (plus.display.resolutionHeight - 50) + "px";
});
这段代码 转自:解决弹出输入法时页面高度变小导致底部上浮的问题

2.如果选项卡在父页面中,并且在页面中的样式中设置了bottom属性,可以使用
mui.plusReady(function(){
var self=plus.webview.currentWebview();
/**

  • 防止 在write页面输入文字的时候 , 输入法把选项卡撑起来
    */
    var parentVebView =self.opener();
    //防止 父页面选项卡被输入法撑起
    window.addEventListener('resize', function() {
    var a=plus.android.invoke(plus.android.currentWebview(),"getHeight") ;
    var b=plus.navigator.getStatusbarHeight();
    var c=plus.screen.resolutionHeight ;
    var d=(c-a-b);
    console.info('webview高度:'+a+" 状态栏高度:"+b+" 屏幕高度:"+c+" 输入法高度:"+d)
    d >0 ? self.setStyle({top: '45px',bottom: '0px'}) : self.setStyle({top: '45px',bottom: '50px'});
    //d > 0 ? parentVebView.evalJS("mui('#nav_id').css('position','absolute');") : parentVebView.evalJS("mui('#nav_id').css('position','fixed');");
    }, false);
    });
    当输入法打开时 重新设置当前webview的 style属性
收起阅读 »

mui主动触发上拉下拉加载

mui.init({
pullRefresh : {
container:refreshContainer,//待刷新区域标识,querySelector能定位的css选择器均可,比如:id、.class等
up : {
contentrefresh : "正在加载...",//可选,正在加载状态时,上拉加载控件上显示的标题内容
contentnomore:'没有更多数据了',//可选,请求完毕若没有更多数据时显示的提醒内容;
callback :pullfresh-function ,
auto:true//页面加载完就加载一次
}
}
});

主动下拉加载
mui('#pullrefresh').pullRefresh().pulldownLoading();
主动上拉加载
mui('#pullrefresh').pullRefresh().pullupLoading();

继续阅读 »

mui.init({
pullRefresh : {
container:refreshContainer,//待刷新区域标识,querySelector能定位的css选择器均可,比如:id、.class等
up : {
contentrefresh : "正在加载...",//可选,正在加载状态时,上拉加载控件上显示的标题内容
contentnomore:'没有更多数据了',//可选,请求完毕若没有更多数据时显示的提醒内容;
callback :pullfresh-function ,
auto:true//页面加载完就加载一次
}
}
});

主动下拉加载
mui('#pullrefresh').pullRefresh().pulldownLoading();
主动上拉加载
mui('#pullrefresh').pullRefresh().pullupLoading();

收起阅读 »

怎么从零开始学习Dcloud的技术,开发手机APP?

5+App开发 mui HBuilder 视频教程 学习

推荐国内首推的跨平台移动APP开发专业培训机构-东翌学院是Dcloud的合作培训机构,跨平台APP开发整体课程在线直播+课程源码+全套视频,最新最全的APP开发,HB和MUI的全套视频,零基础都可以学习,更有高级进修课程,30天最快速的开发跨平台APP!咨询报名QQ:410355878 网址:http://www.dongyixueyuan.com/ 欢迎有意向学习的朋友加好友咨询!谢谢Dcloud提供这么好的平台!

立即学习

继续阅读 »

推荐国内首推的跨平台移动APP开发专业培训机构-东翌学院是Dcloud的合作培训机构,跨平台APP开发整体课程在线直播+课程源码+全套视频,最新最全的APP开发,HB和MUI的全套视频,零基础都可以学习,更有高级进修课程,30天最快速的开发跨平台APP!咨询报名QQ:410355878 网址:http://www.dongyixueyuan.com/ 欢迎有意向学习的朋友加好友咨询!谢谢Dcloud提供这么好的平台!

立即学习

收起阅读 »

HTML5新增标签总结、简单说明

从使用的特点上来看,HTML5相对以前版本来看给人的感觉就是更加人性化。按照以往的页面布局习惯是<div id="article"> 代表内容模块,<div id="aside">代表边栏模块,通过这种方式来区分每个div的区块部分。HTML5就不一样了,一改以往布局习惯换成<article>、<aside> 这些更加语义化的标签。所以说H5增加了这些标签最大的作用就是语义化,便于读取和识辨。因此也更加适合做SEO,容易快速准确的被爬虫读取,就像head和 titile 这样的标签元素一样。同时一些移动设备在解析到这些标签的时候做出特殊提示或者更加人性化的展示 等等。
HTML5新增了哪些标签(来源网络)

标签 标记意义及用法分析/示例 属性/属性值/描述
<article> 定义独立的内容,如论坛帖子、报纸文章、博客条目、用户评论等内容。 支持HTML5的全局属性和事件属性。
<aside> 定义两栏或多栏页面的侧边栏内容,如联系我们、客服、网站公告等内容。 支持HTML5的全局属性和事件属性。
<audio> 定义音频内容,如音乐或其他音频流。
autoplay autoplay 自动播放。
controls controls 显示控件。
loop loop 自动重播。
preload preload 预备播放。如果使用 “autoplay”,则忽略该属性。
src url 音频的URL。
支持HTML5的全局属性和事件属性。
<audio src=”audio.wav”>
您的浏览器不支持 audio 标签。(注:可以在开始标签和结束标签之间加上此文本内容,这样若浏览器不支持此元素,就可以显示出这个信息。)
</audio>

<canvas> 定义图形,如图表和其他图像。(注:<canvas> 只是图形容器,我们必须使用脚本来绘制图形。)
height pixels 设置 canvas 的高度。
width pixels 设置 canvas 的宽度。
支持HTML5的全局属性和事件属性。
<canvas id=”myCanvas”></canvas>
<script type=”text/javascript”>
var canvas=document.getElementById(‘myCanvas’);
var ctx=canvas.getContext(‘2d’);
ctx.fillStyle=’#FFFF00′;
ctx.fillRect(0,0,20,30);
</script>

<command> 标记定义一个命令按钮,比如单选按钮、复选框或按钮。只有当 command 元素位于 menu 元素内时,该元素才是可见的。否则不会显示这个元素,但是可以用它规定键盘快捷键。
checked checked 定义是否被选中。仅用于 radio 或 checkbox 类型
disabled disabled 定义 command 是否可用
icon url 定义作为 command 来显示的图像的url
label text 为 command 定义可见的 label
radiogroup groupname 定义 command 所属的组名。仅在类型为 radio 时使用
type checkbox
command
radio
定义该 command 的类型。默认是 “command”
支持HTML5的全局属性和事件属性。
<menu>
<command onclick=”alert(‘Hello!’)”>Click here.</command>
</menu>

<datalist> 定义选项列表,需与 input 元素配合使用,通过input 元素的 list 属性来绑定,用来定义 input 可能的值。datalist 及其选项不会被显示出来,它仅仅是合法的输入值列表。 支持HTML5的全局属性和事件属性。
<input id=”fruits” list=”fruits” />
<datalist id=”fruits”>
<option value=”Apple”>
<option value=”Banana”>
</datalist>

<details> 用于描述文档或文档某个部分的细节。
open open 定义 details 是否可见
支持HTML5的全局属性和事件属性。
<details>
<summary>Some title.</summary>
<p>Some details about the title.</p>
</details>

<embed> 定义外部的可交互的内容或插件。
height pixels 设置嵌入内容的高度
src url 嵌入内容的 URL
type type 定义嵌入内容的类型
width pixels 设置嵌入内容的宽度
支持HTML5的全局属性和事件属性。
<embed src=”someone.swf” />

<figure> 定义一组媒体内容(图像、图表、照片、代码等)以及它们的标题。如果被删除,则不应对文档流产生影响。 支持HTML5的全局属性和事件属性。
<figure>
<p>The title of the image.</p>
<img src=”someimage.jpg” width=”100″ height=”50″ />
</figure>

<footer> 定义一个页面或一个区域的页脚。可包含文档的作者姓名、创作日期或者联系信息。 支持HTML5的全局属性和事件属性。
<header> 定义一个页面或一个区域的头部。 支持HTML5的全局属性和事件属性。
<hgroup> 定义文件中一个区块的相关信息,使用 <hgroup> 标签对网页或区段(section)的标题进行组合。 支持HTML5的全局属性和事件属性。
<hgroup>
<h1>Welcome my world!</h1>
<h2>This is a title.</h2>
</hgroup>

<keygen> 定义表单里一个生成的键值。规定用于表单的密钥对生成器字段。当提交表单时,私钥存储在本地,公钥发送到服务器。
autofocus autofocus 使 keygen 字段在页面加载时获得焦点
challenge challenge 如果使用,则将 keygen 的值设置为在提交时询问
disabled disabled 禁用 keytag 字段
form formname 定义该 keygen 字段所属的一个或多个表单
keytype rsa 定义 keytype。rsa 生成 RSA 密钥
name fieldname 定义 keygen 元素的唯一名称,用于在提交表单时搜集字段的值。
支持HTML5的全局属性和事件属性。
<form action=”demo_keygen.asp” method=”get”>
Username: <input type=”text” name=”usr_name” />
Encryption: <keygen name=”security” />
<input type=”submit” />
</form>

<mark> 定义有标记的文本。请在需要突出显示文本时使用此标签。 支持HTML5的全局属性和事件属性。
<p>I like <mark>apple</mark> most.</p>

<meter> 定义度量衡。仅用于已知最大和最小值的度量。(注:必须定义度量的范围,既可以在元素的文本中,也可以在 min/max 属性中定义。)
high number 定义度量的值位于哪个点,被界定为高的值
low number 定义度量的值位于哪个点,被界定为低的值
max number 定义最大值。默认值是 1
min number 定义最小值。默认值是 0
optimum number 定义什么样的度量值是最佳的值。如果该值高于 “high” 属性,则意味着值越高越好。如果该值低于 “low” 属性的值,则意味着值越低越好。
value number 定义度量的值
支持HTML5的全局属性和事件属性。
<meter min=”0″ max=”10″>2</meter>
<meter>2 out of 5</meter>
<meter>10%</meter>

<nav> 定义导航链接。(注:如果文档中有“前后”按钮,则应该把它放到 <nav> 元素中。) 支持HTML5的全局属性和事件属性。
<nav>
<a href=”index.asp”>Home</a>
<a href=”Previous.asp”>Previous</a>
<a href=”Next.asp”>Next</a>
</nav>

<output> 定义不同类型的输出,比如脚本的输出。
for id of another element 定义输出域相关的一个或多个元素
form formname 定义输入字段所属的一个或多个表单
name unique name 定义对象的唯一名称。(表单提交时使用)
支持HTML5的全局属性和事件属性。
<progress> 定义任务(如下载)的过程,可以使用此标签来显示 JavaScript 中耗费时间的函数的进度。
max number 定义完成的值
value number 定义进程的当前值
支持HTML5的全局属性和事件属性。
<progress>
<span id=”progress”>15</span>%
</progress>

<ruby> 定义 ruby 注释(中文注音或字符)。在东亚使用,显示的是东亚字符的发音。ruby 元素由一个或多个字符(需要一个解释/发音)和一个提供该信息的 rt 元素组成,还包括可选的 rp 元素,定义当浏览器不支持 “ruby” 元素时显示的内容。 支持HTML5的全局属性和事件属性。
<section> 定义文档中的节(section、区段)。比如章节、页眉、页脚或文档中的其他部分。
cite URL 当 section 摘自 web 的时候使用
支持HTML5的全局属性和事件属性。
<source> 为媒介元素(比如 <video> 和 <audio>)定义媒介资源。
media media query 定义媒介资源的类型,供浏览器决定是否下载
src url 媒介的 URL
type numeric value 定义播放器在音频流中播放起始位置。默认是从开头播放。
支持HTML5的全局属性和事件属性。
<time> 定义一个日期/时间,该元素能够以机器可读的方式对日期和时间进行编码,举例说,用户代理能够把生日提醒或排定的事件添加到用户日程表中,搜索引擎也能够生成更智能的搜索结果。
datetime datetime 规定日期或时间。否则,由元素的内容给定日期或时间
pubdate pubdate 指示 <time> 元素中的日期或时间是文档的发布日期
支持HTML5的全局属性和事件属性。
<p>大家都是早上 <time>9:00</time> 上班。</p>
<p><time datetime=”2012-01-01″>元旦</time>晚会。</p>

<video> 定义视频,比如电影片段或其他视频流。
autoplay autoplay 自动播放。
controls controls 显示控件。
height pixels 设置视频播放器的高度
loop loop 自动重播。
preload preload 预备播放。如果使用 “autoplay”,则忽略该属性。
src url 视频的URL。
width pixels 设置视频播放器的宽度
支持HTML5的全局属性和事件属性。
<video src=”movie.ogg” controls=”controls”>
您的浏览器不支持 video 标签。(注:可以在开始标签和结束标签之间加上此文本内容,这样若浏览器不支持此元素,就可以显示出这个信息。)
</video>

继续阅读 »

从使用的特点上来看,HTML5相对以前版本来看给人的感觉就是更加人性化。按照以往的页面布局习惯是<div id="article"> 代表内容模块,<div id="aside">代表边栏模块,通过这种方式来区分每个div的区块部分。HTML5就不一样了,一改以往布局习惯换成<article>、<aside> 这些更加语义化的标签。所以说H5增加了这些标签最大的作用就是语义化,便于读取和识辨。因此也更加适合做SEO,容易快速准确的被爬虫读取,就像head和 titile 这样的标签元素一样。同时一些移动设备在解析到这些标签的时候做出特殊提示或者更加人性化的展示 等等。
HTML5新增了哪些标签(来源网络)

标签 标记意义及用法分析/示例 属性/属性值/描述
<article> 定义独立的内容,如论坛帖子、报纸文章、博客条目、用户评论等内容。 支持HTML5的全局属性和事件属性。
<aside> 定义两栏或多栏页面的侧边栏内容,如联系我们、客服、网站公告等内容。 支持HTML5的全局属性和事件属性。
<audio> 定义音频内容,如音乐或其他音频流。
autoplay autoplay 自动播放。
controls controls 显示控件。
loop loop 自动重播。
preload preload 预备播放。如果使用 “autoplay”,则忽略该属性。
src url 音频的URL。
支持HTML5的全局属性和事件属性。
<audio src=”audio.wav”>
您的浏览器不支持 audio 标签。(注:可以在开始标签和结束标签之间加上此文本内容,这样若浏览器不支持此元素,就可以显示出这个信息。)
</audio>

<canvas> 定义图形,如图表和其他图像。(注:<canvas> 只是图形容器,我们必须使用脚本来绘制图形。)
height pixels 设置 canvas 的高度。
width pixels 设置 canvas 的宽度。
支持HTML5的全局属性和事件属性。
<canvas id=”myCanvas”></canvas>
<script type=”text/javascript”>
var canvas=document.getElementById(‘myCanvas’);
var ctx=canvas.getContext(‘2d’);
ctx.fillStyle=’#FFFF00′;
ctx.fillRect(0,0,20,30);
</script>

<command> 标记定义一个命令按钮,比如单选按钮、复选框或按钮。只有当 command 元素位于 menu 元素内时,该元素才是可见的。否则不会显示这个元素,但是可以用它规定键盘快捷键。
checked checked 定义是否被选中。仅用于 radio 或 checkbox 类型
disabled disabled 定义 command 是否可用
icon url 定义作为 command 来显示的图像的url
label text 为 command 定义可见的 label
radiogroup groupname 定义 command 所属的组名。仅在类型为 radio 时使用
type checkbox
command
radio
定义该 command 的类型。默认是 “command”
支持HTML5的全局属性和事件属性。
<menu>
<command onclick=”alert(‘Hello!’)”>Click here.</command>
</menu>

<datalist> 定义选项列表,需与 input 元素配合使用,通过input 元素的 list 属性来绑定,用来定义 input 可能的值。datalist 及其选项不会被显示出来,它仅仅是合法的输入值列表。 支持HTML5的全局属性和事件属性。
<input id=”fruits” list=”fruits” />
<datalist id=”fruits”>
<option value=”Apple”>
<option value=”Banana”>
</datalist>

<details> 用于描述文档或文档某个部分的细节。
open open 定义 details 是否可见
支持HTML5的全局属性和事件属性。
<details>
<summary>Some title.</summary>
<p>Some details about the title.</p>
</details>

<embed> 定义外部的可交互的内容或插件。
height pixels 设置嵌入内容的高度
src url 嵌入内容的 URL
type type 定义嵌入内容的类型
width pixels 设置嵌入内容的宽度
支持HTML5的全局属性和事件属性。
<embed src=”someone.swf” />

<figure> 定义一组媒体内容(图像、图表、照片、代码等)以及它们的标题。如果被删除,则不应对文档流产生影响。 支持HTML5的全局属性和事件属性。
<figure>
<p>The title of the image.</p>
<img src=”someimage.jpg” width=”100″ height=”50″ />
</figure>

<footer> 定义一个页面或一个区域的页脚。可包含文档的作者姓名、创作日期或者联系信息。 支持HTML5的全局属性和事件属性。
<header> 定义一个页面或一个区域的头部。 支持HTML5的全局属性和事件属性。
<hgroup> 定义文件中一个区块的相关信息,使用 <hgroup> 标签对网页或区段(section)的标题进行组合。 支持HTML5的全局属性和事件属性。
<hgroup>
<h1>Welcome my world!</h1>
<h2>This is a title.</h2>
</hgroup>

<keygen> 定义表单里一个生成的键值。规定用于表单的密钥对生成器字段。当提交表单时,私钥存储在本地,公钥发送到服务器。
autofocus autofocus 使 keygen 字段在页面加载时获得焦点
challenge challenge 如果使用,则将 keygen 的值设置为在提交时询问
disabled disabled 禁用 keytag 字段
form formname 定义该 keygen 字段所属的一个或多个表单
keytype rsa 定义 keytype。rsa 生成 RSA 密钥
name fieldname 定义 keygen 元素的唯一名称,用于在提交表单时搜集字段的值。
支持HTML5的全局属性和事件属性。
<form action=”demo_keygen.asp” method=”get”>
Username: <input type=”text” name=”usr_name” />
Encryption: <keygen name=”security” />
<input type=”submit” />
</form>

<mark> 定义有标记的文本。请在需要突出显示文本时使用此标签。 支持HTML5的全局属性和事件属性。
<p>I like <mark>apple</mark> most.</p>

<meter> 定义度量衡。仅用于已知最大和最小值的度量。(注:必须定义度量的范围,既可以在元素的文本中,也可以在 min/max 属性中定义。)
high number 定义度量的值位于哪个点,被界定为高的值
low number 定义度量的值位于哪个点,被界定为低的值
max number 定义最大值。默认值是 1
min number 定义最小值。默认值是 0
optimum number 定义什么样的度量值是最佳的值。如果该值高于 “high” 属性,则意味着值越高越好。如果该值低于 “low” 属性的值,则意味着值越低越好。
value number 定义度量的值
支持HTML5的全局属性和事件属性。
<meter min=”0″ max=”10″>2</meter>
<meter>2 out of 5</meter>
<meter>10%</meter>

<nav> 定义导航链接。(注:如果文档中有“前后”按钮,则应该把它放到 <nav> 元素中。) 支持HTML5的全局属性和事件属性。
<nav>
<a href=”index.asp”>Home</a>
<a href=”Previous.asp”>Previous</a>
<a href=”Next.asp”>Next</a>
</nav>

<output> 定义不同类型的输出,比如脚本的输出。
for id of another element 定义输出域相关的一个或多个元素
form formname 定义输入字段所属的一个或多个表单
name unique name 定义对象的唯一名称。(表单提交时使用)
支持HTML5的全局属性和事件属性。
<progress> 定义任务(如下载)的过程,可以使用此标签来显示 JavaScript 中耗费时间的函数的进度。
max number 定义完成的值
value number 定义进程的当前值
支持HTML5的全局属性和事件属性。
<progress>
<span id=”progress”>15</span>%
</progress>

<ruby> 定义 ruby 注释(中文注音或字符)。在东亚使用,显示的是东亚字符的发音。ruby 元素由一个或多个字符(需要一个解释/发音)和一个提供该信息的 rt 元素组成,还包括可选的 rp 元素,定义当浏览器不支持 “ruby” 元素时显示的内容。 支持HTML5的全局属性和事件属性。
<section> 定义文档中的节(section、区段)。比如章节、页眉、页脚或文档中的其他部分。
cite URL 当 section 摘自 web 的时候使用
支持HTML5的全局属性和事件属性。
<source> 为媒介元素(比如 <video> 和 <audio>)定义媒介资源。
media media query 定义媒介资源的类型,供浏览器决定是否下载
src url 媒介的 URL
type numeric value 定义播放器在音频流中播放起始位置。默认是从开头播放。
支持HTML5的全局属性和事件属性。
<time> 定义一个日期/时间,该元素能够以机器可读的方式对日期和时间进行编码,举例说,用户代理能够把生日提醒或排定的事件添加到用户日程表中,搜索引擎也能够生成更智能的搜索结果。
datetime datetime 规定日期或时间。否则,由元素的内容给定日期或时间
pubdate pubdate 指示 <time> 元素中的日期或时间是文档的发布日期
支持HTML5的全局属性和事件属性。
<p>大家都是早上 <time>9:00</time> 上班。</p>
<p><time datetime=”2012-01-01″>元旦</time>晚会。</p>

<video> 定义视频,比如电影片段或其他视频流。
autoplay autoplay 自动播放。
controls controls 显示控件。
height pixels 设置视频播放器的高度
loop loop 自动重播。
preload preload 预备播放。如果使用 “autoplay”,则忽略该属性。
src url 视频的URL。
width pixels 设置视频播放器的宽度
支持HTML5的全局属性和事件属性。
<video src=”movie.ogg” controls=”controls”>
您的浏览器不支持 video 标签。(注:可以在开始标签和结束标签之间加上此文本内容,这样若浏览器不支持此元素,就可以显示出这个信息。)
</video>

收起阅读 »

安卓上用推送通知后续操作打开url+url scheme实现透传消息效果,相比直接使用透传的优点是:传递的数据量大,到达率高

推送

安卓上用推送通知后续操作打开url url scheme实现透传消息效果,相比直接使用透传的优点是:传递的数据量大,到达率高

安卓上用推送通知后续操作打开url url scheme实现透传消息效果,相比直接使用透传的优点是:传递的数据量大,到达率高

给各位新人分享一个APP开发经验附带源码[上啦加载下拉刷新后通过ajax获取网络数据,页面传值,列表点击]

5 App开发

这是我昨天用hbuider开发的一款练手的APP,数据是调用百度API市场提供的一个微信精选API 主要涉及的操作有页面之间的传值,
上啦加载下拉刷新后执行ajax获取新的数据 ,列表点击事件

PS:其实我也是一个小白,在开发 过程中请教过很多高手指点,怀疑人生很久后才独立开发出这款APP的 界面偷了论坛某位大神写的,

内置浏览器也是偷的论坛某位大神发的 嘻嘻 看图

继续阅读 »

这是我昨天用hbuider开发的一款练手的APP,数据是调用百度API市场提供的一个微信精选API 主要涉及的操作有页面之间的传值,
上啦加载下拉刷新后执行ajax获取新的数据 ,列表点击事件

PS:其实我也是一个小白,在开发 过程中请教过很多高手指点,怀疑人生很久后才独立开发出这款APP的 界面偷了论坛某位大神写的,

内置浏览器也是偷的论坛某位大神发的 嘻嘻 看图

收起阅读 »

录音文件与Base64编码相互转换的方法

技术分享

前言

最近有几个朋友一直在问语音文件怎么转base64字符串进行发送上传,base64字符串又如何转成文件,论坛中已经有多篇问题的帖子有介绍,这里只是稍微整理,方便大家可以更加方便的使用,首先看效果:

录音文件转成base64字符串

hello mui 演示app中im-chat.html有演示案例,通过hold和release控制录音的长度,即长按按钮开始录音,释放就停止录音,上拉取消发送录音。

html部分

<button id="recorder" type="button" class="mui-btn mui-btn-blue mui-btn-block">录制语音文件转base64字符串</button>

js部分

mui.init中首先需要配置手势事件

mui.init({  
    gestureConfig: {  
        tap: true, //默认为true  
        doubletap: true, //默认为false  
        longtap: true, //默认为false  
        swipe: true, //默认为true  
        drag: true, //默认为true  
        hold: true, //默认为false,不监听  
        release: true //默认为false,不监听  
    }  
});

录音逻辑控制,按住按钮弹出录音提示框,并且对录音时长进行控制,录音时间太短取消操作,手指上划,取消发送。

var MIN_SOUND_TIME = 800;  
var recorder = null;  
var startTimestamp = null;  
var stopTimestamp = null;  
var stopTimer = null;  
var recordCancel = false;  

var soundAlert = document.getElementById("sound-alert");  
var audioTips = document.getElementById("audio-tips");  

// 控制录音弹出框是否播放  
var setSoundAlertVisable=function(show){  
    if(show){  
        soundAlert.style.display = 'block';  
        soundAlert.style.opacity = 1;  
    }else{  
        soundAlert.style.opacity = 0;  
        //  完成再真正隐藏  
        setTimeout(function(){  
            soundAlert.style.display = 'none';  
        },200);  
    }  
};  

mui.plusReady(function () {  
    /**  
     * 录制语音文件转base64字符串  
     */  
    // 按住录音(长按开始录音)  
    document.querySelector('#recorder').addEventListener('hold',function () {  
        recordCancel = false;  
    if(stopTimer)clearTimeout(stopTimer);  

    audioTips.innerHTML = "手指上划,取消发送";  
    soundAlert.classList.remove('rprogress-sigh');  
    setSoundAlertVisable(true);  

    // 获取当前设备的录音对象  
        recorder = plus.audio.getRecorder();  
        startTimestamp = (new Date()).getTime();  
        recorder.record({  
            filename:"_doc/audio/",  
            format:"amr" //iOS平台支持"wav"、"aac"、"amr"格式,默认为"wav"  
        }, function (path) {  
            if (recordCancel) return;  
            console.log("path:"+path);  
            Audio2dataURL(path);  
        }, function ( e ) {  
            mui.toast("录音出现异常: " + e.message );  
        });  
    })  

    // 释放保存(松手保存)  
    document.querySelector('#recorder').addEventListener('release',function () {  
        if (audioTips.classList.contains("cancel")) {  
            audioTips.classList.remove("cancel");  
            audioTips.innerHTML = "手指上划,取消发送";  
        }  
        // 判断录音时间  
        stopTimestamp = (new Date()).getTime();  
        if (stopTimestamp - startTimestamp < 800) {  
            audioTips.innerHTML = "录音时间太短";  
            soundAlert.classList.add('rprogress-sigh');  
            recordCancel = true;  
            stopTimer=setTimeout(function(){  
                setSoundAlertVisable(false);  
            },800);  
        }else{  
            setSoundAlertVisable(false);  
        }  
        recorder.stop();  
    })  

    // 拖动屏幕(手指上划,取消发送)  
    document.body.addEventListener('drag', function(event) {  
        if (Math.abs(event.detail.deltaY) > 50) {  
            if (!recordCancel) {  
                recordCancel = true;  
                if (!audioTips.classList.contains("cancel")) {  
                    audioTips.classList.add("cancel");  
                }  
                audioTips.innerHTML = "松开手指,取消发送";  
            }  
        } else {  
            if (recordCancel) {  
                recordCancel = false;  
                if (audioTips.classList.contains("cancel")) {  
                    audioTips.classList.remove("cancel");  
                }  
                audioTips.innerHTML = "手指上划,取消发送";  
            }  
        }  
      }, false);  
})

当录音成功后,我们可以将录音文件转成base64字符串,用于网络传输。

/**  
 * 录音语音文件转base64字符串  
 * @param {Object} path  
 */  
function Audio2dataURL (path) {  
    plus.io.resolveLocalFileSystemURL(path, function(entry){  
        entry.file(function(file){  
            var reader = new plus.io.FileReader();  
            reader.onloadend = function (e) {  
                console.log(e.target.result);  
            };  
            reader.readAsDataURL(file);  
        },function(e){  
            mui.toast("读写出现异常: " + e.message );  
        })  
    })  
}

至此我们完成了录音语音文件转base64字符串,反过来我们需要将base64字符串转成语音文件。

base64字符串转成语音文件

我们可以封装如下方法:

/**  
 * base64字符串转成语音文件(参考http://ask.dcloud.net.cn/question/16935)  
 * @param {Object} base64Str  
 * @param {Object} callback  
 */  
function dataURL2Audio (base64Str, callback) {  
    var base64Str = base64Str.replace('data:audio/amr;base64,','');  
    var audioName = (new Date()).valueOf() + '.amr';  

    plus.io.requestFileSystem(plus.io.PRIVATE_DOC,function(fs){  
        fs.root.getFile(audioName,{create:true},function(entry){  
            // 获得平台绝对路径  
            var fullPath = entry.fullPath;  
            if(mui.os.android){    
                // 读取音频  
                var Base64 = plus.android.importClass("android.util.Base64");  
                var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");  
                try{  
                    var out = new FileOutputStream(fullPath);  
                    var bytes = Base64.decode(base64Str, Base64.DEFAULT);  
                    out.write(bytes);   
                    out.close();  
                    // 回调  
                    callback && callback(entry);  
                }catch(e){  
                    console.log(e.message);  
                }  
            }else if(mui.os.ios){  
                var NSData = plus.ios.importClass('NSData');  
                var nsData = new NSData();  
                nsData = nsData.initWithBase64EncodedStringoptions(base64Str,0);  
                if (nsData) {  
                    nsData.plusCallMethod({writeToFile: fullPath,atomically:true});  
                    plus.ios.deleteObject(nsData);  
                }  
                // 回调  
                callback && callback(entry);  
            }  
        })  
    })  
}

调用方法如下:

html部分:

<button id="player" type="button" class="mui-btn mui-btn-blue mui-btn-block">base64字符串转成语音文件播放</button>

js部分:

/**  
 * base64字符串转成语音文件播放  
 */  
document.querySelector('#player').addEventListener('tap',function () {  
        // 语音文件Base64编码(由于编码过长影响阅读体验,请查看工程验证)  
     var base64Str = ' '   

        // 转成.amr文件播放  
    dataURL2Audio(base64Str, function(entry){  
        var toURL = entry.toURL();  
        // 播放音频  
        playAudio(toURL);  
    })  
})  

/**  
 * 播放音频  
 * @param {Object} path  
 */  
function playAudio (path) {  
    var player = plus.audio.createPlayer(path);  
    player.play(function(){  
        mui.toast("播放成功");  
    }, function(e) {  
        mui.toast("播放失败");  
    });   
}

写在后面

本文以语音文件为例说明5+中语音文件与Base64编码的相互转换,对于图片与Base64编码的转换方法请参考nativeObj Bitmap: 原生图片对象,可以通过loadBase64Data方法加载Base64编码格式图片到Bitmap对象,通过toBase64Data方法获取图片的Base64编码数据。对于一般性文件,建议使用h5 File API,详细可以参考我这篇文章:
JavaScript进阶学习(三)—— 基于html5 File API的文件操作

本文详细代码请查看附件工程。

继续阅读 »

前言

最近有几个朋友一直在问语音文件怎么转base64字符串进行发送上传,base64字符串又如何转成文件,论坛中已经有多篇问题的帖子有介绍,这里只是稍微整理,方便大家可以更加方便的使用,首先看效果:

录音文件转成base64字符串

hello mui 演示app中im-chat.html有演示案例,通过hold和release控制录音的长度,即长按按钮开始录音,释放就停止录音,上拉取消发送录音。

html部分

<button id="recorder" type="button" class="mui-btn mui-btn-blue mui-btn-block">录制语音文件转base64字符串</button>

js部分

mui.init中首先需要配置手势事件

mui.init({  
    gestureConfig: {  
        tap: true, //默认为true  
        doubletap: true, //默认为false  
        longtap: true, //默认为false  
        swipe: true, //默认为true  
        drag: true, //默认为true  
        hold: true, //默认为false,不监听  
        release: true //默认为false,不监听  
    }  
});

录音逻辑控制,按住按钮弹出录音提示框,并且对录音时长进行控制,录音时间太短取消操作,手指上划,取消发送。

var MIN_SOUND_TIME = 800;  
var recorder = null;  
var startTimestamp = null;  
var stopTimestamp = null;  
var stopTimer = null;  
var recordCancel = false;  

var soundAlert = document.getElementById("sound-alert");  
var audioTips = document.getElementById("audio-tips");  

// 控制录音弹出框是否播放  
var setSoundAlertVisable=function(show){  
    if(show){  
        soundAlert.style.display = 'block';  
        soundAlert.style.opacity = 1;  
    }else{  
        soundAlert.style.opacity = 0;  
        //  完成再真正隐藏  
        setTimeout(function(){  
            soundAlert.style.display = 'none';  
        },200);  
    }  
};  

mui.plusReady(function () {  
    /**  
     * 录制语音文件转base64字符串  
     */  
    // 按住录音(长按开始录音)  
    document.querySelector('#recorder').addEventListener('hold',function () {  
        recordCancel = false;  
    if(stopTimer)clearTimeout(stopTimer);  

    audioTips.innerHTML = "手指上划,取消发送";  
    soundAlert.classList.remove('rprogress-sigh');  
    setSoundAlertVisable(true);  

    // 获取当前设备的录音对象  
        recorder = plus.audio.getRecorder();  
        startTimestamp = (new Date()).getTime();  
        recorder.record({  
            filename:"_doc/audio/",  
            format:"amr" //iOS平台支持"wav"、"aac"、"amr"格式,默认为"wav"  
        }, function (path) {  
            if (recordCancel) return;  
            console.log("path:"+path);  
            Audio2dataURL(path);  
        }, function ( e ) {  
            mui.toast("录音出现异常: " + e.message );  
        });  
    })  

    // 释放保存(松手保存)  
    document.querySelector('#recorder').addEventListener('release',function () {  
        if (audioTips.classList.contains("cancel")) {  
            audioTips.classList.remove("cancel");  
            audioTips.innerHTML = "手指上划,取消发送";  
        }  
        // 判断录音时间  
        stopTimestamp = (new Date()).getTime();  
        if (stopTimestamp - startTimestamp < 800) {  
            audioTips.innerHTML = "录音时间太短";  
            soundAlert.classList.add('rprogress-sigh');  
            recordCancel = true;  
            stopTimer=setTimeout(function(){  
                setSoundAlertVisable(false);  
            },800);  
        }else{  
            setSoundAlertVisable(false);  
        }  
        recorder.stop();  
    })  

    // 拖动屏幕(手指上划,取消发送)  
    document.body.addEventListener('drag', function(event) {  
        if (Math.abs(event.detail.deltaY) > 50) {  
            if (!recordCancel) {  
                recordCancel = true;  
                if (!audioTips.classList.contains("cancel")) {  
                    audioTips.classList.add("cancel");  
                }  
                audioTips.innerHTML = "松开手指,取消发送";  
            }  
        } else {  
            if (recordCancel) {  
                recordCancel = false;  
                if (audioTips.classList.contains("cancel")) {  
                    audioTips.classList.remove("cancel");  
                }  
                audioTips.innerHTML = "手指上划,取消发送";  
            }  
        }  
      }, false);  
})

当录音成功后,我们可以将录音文件转成base64字符串,用于网络传输。

/**  
 * 录音语音文件转base64字符串  
 * @param {Object} path  
 */  
function Audio2dataURL (path) {  
    plus.io.resolveLocalFileSystemURL(path, function(entry){  
        entry.file(function(file){  
            var reader = new plus.io.FileReader();  
            reader.onloadend = function (e) {  
                console.log(e.target.result);  
            };  
            reader.readAsDataURL(file);  
        },function(e){  
            mui.toast("读写出现异常: " + e.message );  
        })  
    })  
}

至此我们完成了录音语音文件转base64字符串,反过来我们需要将base64字符串转成语音文件。

base64字符串转成语音文件

我们可以封装如下方法:

/**  
 * base64字符串转成语音文件(参考http://ask.dcloud.net.cn/question/16935)  
 * @param {Object} base64Str  
 * @param {Object} callback  
 */  
function dataURL2Audio (base64Str, callback) {  
    var base64Str = base64Str.replace('data:audio/amr;base64,','');  
    var audioName = (new Date()).valueOf() + '.amr';  

    plus.io.requestFileSystem(plus.io.PRIVATE_DOC,function(fs){  
        fs.root.getFile(audioName,{create:true},function(entry){  
            // 获得平台绝对路径  
            var fullPath = entry.fullPath;  
            if(mui.os.android){    
                // 读取音频  
                var Base64 = plus.android.importClass("android.util.Base64");  
                var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");  
                try{  
                    var out = new FileOutputStream(fullPath);  
                    var bytes = Base64.decode(base64Str, Base64.DEFAULT);  
                    out.write(bytes);   
                    out.close();  
                    // 回调  
                    callback && callback(entry);  
                }catch(e){  
                    console.log(e.message);  
                }  
            }else if(mui.os.ios){  
                var NSData = plus.ios.importClass('NSData');  
                var nsData = new NSData();  
                nsData = nsData.initWithBase64EncodedStringoptions(base64Str,0);  
                if (nsData) {  
                    nsData.plusCallMethod({writeToFile: fullPath,atomically:true});  
                    plus.ios.deleteObject(nsData);  
                }  
                // 回调  
                callback && callback(entry);  
            }  
        })  
    })  
}

调用方法如下:

html部分:

<button id="player" type="button" class="mui-btn mui-btn-blue mui-btn-block">base64字符串转成语音文件播放</button>

js部分:

/**  
 * base64字符串转成语音文件播放  
 */  
document.querySelector('#player').addEventListener('tap',function () {  
        // 语音文件Base64编码(由于编码过长影响阅读体验,请查看工程验证)  
     var base64Str = ' '   

        // 转成.amr文件播放  
    dataURL2Audio(base64Str, function(entry){  
        var toURL = entry.toURL();  
        // 播放音频  
        playAudio(toURL);  
    })  
})  

/**  
 * 播放音频  
 * @param {Object} path  
 */  
function playAudio (path) {  
    var player = plus.audio.createPlayer(path);  
    player.play(function(){  
        mui.toast("播放成功");  
    }, function(e) {  
        mui.toast("播放失败");  
    });   
}

写在后面

本文以语音文件为例说明5+中语音文件与Base64编码的相互转换,对于图片与Base64编码的转换方法请参考nativeObj Bitmap: 原生图片对象,可以通过loadBase64Data方法加载Base64编码格式图片到Bitmap对象,通过toBase64Data方法获取图片的Base64编码数据。对于一般性文件,建议使用h5 File API,详细可以参考我这篇文章:
JavaScript进阶学习(三)—— 基于html5 File API的文件操作

本文详细代码请查看附件工程。

收起阅读 »

【第一课学习】mui.ajax跨域绑定列表实例 by Xueby

Asp.Net的MVC4版后台请求json代码
public JsonResult GetUserInfo()
{
List<Member> list = _memberService.GetTopMemberList(10, "1=1", "MemberId Desc");
var dataList = list.Select(p => new
{
p.UserName,
p.Email
});
//ajax请求必须加
HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", "*");
HttpContext.Response.AppendHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return Json(new { dataList, result = true }, JsonRequestBehavior.AllowGet);
}

前台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>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet" />
<script type="text/javascript" charset="utf-8">
(function($) {
mui.ajax({
type: "GET",
url: "http://localhost:8080/mobile/Member/GetUserInfo", //跨域URL
dataType: "json",
success: function(data) {
//alert(JSON.stringify(data.dataList));
var list = document.getElementById("list");
var fragment = document.createDocumentFragment();
var li;
mui.each(data.dataList, function(index, item) {
var id = item.UserName,
name = item.UserName,
author = item.UserName,
picUrl = item.UserName
li = document.createElement('li');
li.className = 'mui-table-view-cell mui-media';
li.innerHTML = '<a class="mui-navigate-right" id=' + id + '>' +
'<img class="mui-media-object mui-pull-left" src="http://www.dcloud.io/hellomui/images/1.jpg"/>' +
'<div class="mui-media-body">' + name +
'<p class="mui-ellipsis">' + author + '</p>' +
'</div>' +
'</a>';
fragment.appendChild(li);
})
list.appendChild(fragment)
}
});
})(mui);
</script>
</head>
<body>
<div class="mui-content">
<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>
</div>
</body>
</html>

继续阅读 »

Asp.Net的MVC4版后台请求json代码
public JsonResult GetUserInfo()
{
List<Member> list = _memberService.GetTopMemberList(10, "1=1", "MemberId Desc");
var dataList = list.Select(p => new
{
p.UserName,
p.Email
});
//ajax请求必须加
HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", "*");
HttpContext.Response.AppendHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return Json(new { dataList, result = true }, JsonRequestBehavior.AllowGet);
}

前台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>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet" />
<script type="text/javascript" charset="utf-8">
(function($) {
mui.ajax({
type: "GET",
url: "http://localhost:8080/mobile/Member/GetUserInfo", //跨域URL
dataType: "json",
success: function(data) {
//alert(JSON.stringify(data.dataList));
var list = document.getElementById("list");
var fragment = document.createDocumentFragment();
var li;
mui.each(data.dataList, function(index, item) {
var id = item.UserName,
name = item.UserName,
author = item.UserName,
picUrl = item.UserName
li = document.createElement('li');
li.className = 'mui-table-view-cell mui-media';
li.innerHTML = '<a class="mui-navigate-right" id=' + id + '>' +
'<img class="mui-media-object mui-pull-left" src="http://www.dcloud.io/hellomui/images/1.jpg"/>' +
'<div class="mui-media-body">' + name +
'<p class="mui-ellipsis">' + author + '</p>' +
'</div>' +
'</a>';
fragment.appendChild(li);
})
list.appendChild(fragment)
}
});
})(mui);
</script>
</head>
<body>
<div class="mui-content">
<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>
</div>
</body>
</html>

收起阅读 »

在github上发现的一个mui的拓展,可以直接用

mui

作者很懒,没有写说明,看了一下代码,可以拿来用,主要封装了常用的一些功能,比如登陆,发送ajax请求,正则判断等:

https://github.com/ionepub/mui.common.js

作者很懒,没有写说明,看了一下代码,可以拿来用,主要封装了常用的一些功能,比如登陆,发送ajax请求,正则判断等:

https://github.com/ionepub/mui.common.js

推送使用中的各种坑

推送

最近做的app中使用到了推送,就直接使用官方集成的个推,然后按照官方案例看了一遍又一遍,写了一遍又一遍,app打包了一遍又一遍,终于算是弄好了安卓版,ios版还没弄呢。现在把一些踩过的坑跟大家分享下,主要是在问答里实在是找不到答案啊!
我使用的是最新的mui(3.2)、hbuilder(7.3.2.201607212211)。
我先描述下,我要求的推送效果:app不管在线还是离线,系统通知栏中都显示消息,点击消息按照消息里的要求打开指定页面显示内容。接下来我一步一步分析下。
1、注册个推,填写appid等,这就不说了;确保安卓系统中app的push进程没有被安全软件杀死。
2、推送模板:个推的模板有好几个,为了能给安卓和ios都能推送,只能选择透传消息模板。
3、透传消息模板又分成标准数据和非标准数据,标准数据格式为:{title:'标题',content:'内容',payload:'数据'},非标准就是不按这个标准格式来的^_^。那到底选择哪个呢?这个是我踩得最惨的坑!!!按官方文档,标准格式会在通知栏里显示消息,点击消息后触发‘click’事件,可是经过我测试,点击消息后根本不触发‘click’事件!重要的事情说三遍:标准格式点击消息后不触发‘click’事件!标准格式点击消息后不触发‘click’事件!标准格式点击消息后不触发‘click’事件!不知道这个标准格式不触发‘click’事件是bug还是原本就这样??!!我后来尝试了非标准格式,在‘receive’里接受透传数据,然后创建本地消息(plus.push.createMessage),系统通知栏能正常显示消息,点击后顺利触发‘click’事件,但是当app不在线(就是被关闭了,push进程还在),receive事件就不执行了,自然就不能创建系统通知了。所以为了实现我最初要的推送效果,我只能选择标准透传数据模板。
4、如何获得透传数据?刚才我说过标准格式不触发‘click’事件,那怎么获得透传数据,并打开我们指定的页面呢?这里需要使用到app的启动参数plus.runtime.arguments。如果app是启动状态,不管前台还是后台,都可以用新意图事件来获得启动参数,如果app是未启动状态,可以在plusReady里获得启动参数。直接上代码

mui.plusReady(function() {  
    //仅支持竖屏显示  
    plus.screen.lockOrientation("portrait-primary");  

    document.addEventListener("newintent", function() {  
        openWebviewFromOthers();  
    });  

    plus.push.addEventListener("click", function(msg) {  
        console.log("push click");  
        pushGetRun(msg.payload);  
    }, false);  
    plus.push.addEventListener("receive", function(msg) {  
        //获取透传数据  
        var data = JSON.parse(msg.payload);  
        //创建本地消息  
        //plus.push.createMessage(data.content, data.payload, {  
        //    title: data.title,  
        //    cover: false  
        //});  
    }, false);  
        openWebviewFromOthers();  
});  
function pushGetRun(payload) {  
    payload = JSON.parse(payload);  
    var id = payload.id;  
    var autoShow = payload.autoshow;  
    var event = payload.event;  
    var params = JSON.stringify(payload.params);  
    ......//用参数打开指定页面  
}  
//获取通知栏(app未启动)点击、第三方程序启动本app  
function openWebviewFromOthers() {  
    var args = plus.runtime.arguments;  
        if(args) {  
            pushGetRun(args);  
        }  
}

此代码仅是我个人最近尝试的结果,仅针对安卓版本,如果有误请指正。

继续阅读 »

最近做的app中使用到了推送,就直接使用官方集成的个推,然后按照官方案例看了一遍又一遍,写了一遍又一遍,app打包了一遍又一遍,终于算是弄好了安卓版,ios版还没弄呢。现在把一些踩过的坑跟大家分享下,主要是在问答里实在是找不到答案啊!
我使用的是最新的mui(3.2)、hbuilder(7.3.2.201607212211)。
我先描述下,我要求的推送效果:app不管在线还是离线,系统通知栏中都显示消息,点击消息按照消息里的要求打开指定页面显示内容。接下来我一步一步分析下。
1、注册个推,填写appid等,这就不说了;确保安卓系统中app的push进程没有被安全软件杀死。
2、推送模板:个推的模板有好几个,为了能给安卓和ios都能推送,只能选择透传消息模板。
3、透传消息模板又分成标准数据和非标准数据,标准数据格式为:{title:'标题',content:'内容',payload:'数据'},非标准就是不按这个标准格式来的^_^。那到底选择哪个呢?这个是我踩得最惨的坑!!!按官方文档,标准格式会在通知栏里显示消息,点击消息后触发‘click’事件,可是经过我测试,点击消息后根本不触发‘click’事件!重要的事情说三遍:标准格式点击消息后不触发‘click’事件!标准格式点击消息后不触发‘click’事件!标准格式点击消息后不触发‘click’事件!不知道这个标准格式不触发‘click’事件是bug还是原本就这样??!!我后来尝试了非标准格式,在‘receive’里接受透传数据,然后创建本地消息(plus.push.createMessage),系统通知栏能正常显示消息,点击后顺利触发‘click’事件,但是当app不在线(就是被关闭了,push进程还在),receive事件就不执行了,自然就不能创建系统通知了。所以为了实现我最初要的推送效果,我只能选择标准透传数据模板。
4、如何获得透传数据?刚才我说过标准格式不触发‘click’事件,那怎么获得透传数据,并打开我们指定的页面呢?这里需要使用到app的启动参数plus.runtime.arguments。如果app是启动状态,不管前台还是后台,都可以用新意图事件来获得启动参数,如果app是未启动状态,可以在plusReady里获得启动参数。直接上代码

mui.plusReady(function() {  
    //仅支持竖屏显示  
    plus.screen.lockOrientation("portrait-primary");  

    document.addEventListener("newintent", function() {  
        openWebviewFromOthers();  
    });  

    plus.push.addEventListener("click", function(msg) {  
        console.log("push click");  
        pushGetRun(msg.payload);  
    }, false);  
    plus.push.addEventListener("receive", function(msg) {  
        //获取透传数据  
        var data = JSON.parse(msg.payload);  
        //创建本地消息  
        //plus.push.createMessage(data.content, data.payload, {  
        //    title: data.title,  
        //    cover: false  
        //});  
    }, false);  
        openWebviewFromOthers();  
});  
function pushGetRun(payload) {  
    payload = JSON.parse(payload);  
    var id = payload.id;  
    var autoShow = payload.autoshow;  
    var event = payload.event;  
    var params = JSON.stringify(payload.params);  
    ......//用参数打开指定页面  
}  
//获取通知栏(app未启动)点击、第三方程序启动本app  
function openWebviewFromOthers() {  
    var args = plus.runtime.arguments;  
        if(args) {  
            pushGetRun(args);  
        }  
}

此代码仅是我个人最近尝试的结果,仅针对安卓版本,如果有误请指正。

收起阅读 »