Skip to content

推荐几个最优秀的关于mobile web介绍的PPT

2011 十二月 31
by admin

1、Mobile HTML,CSS,and JavasScript

Mobile HTML,CSS,and JavasScript
url:  http://www.slideshare.net/franksvalli/mobile-html-css-and-javascript

2、Mobile Web & HTML5 Performance Optimization
Mobile Web & HTML5 Performance Optimization

url: http://www.slideshare.net/firt/mobile-web-html5-performance-optimization

3、HTML5, CSS3, and other fancy buzzwords
HTML5, CSS3, and other fancy buzzwords

url: http://www.slideshare.net/batmoo/html5-css3-and-other-fancy-buzzwords

android浏览器播放FLASH的问题

2011 十二月 8
by admin

背景:
momo 3g版,需要在手机WEB上播放录音(mp3格式),用了audio标签,不过发现android(2.2,2.3)对这个html5标签支持不好,iphone4完全正常。

判断方法是:

1、(‘Audio’ in window)  && !! new Audio().canPlayType(‘audio/mpeg’) 确定用audio标签

核心代码:

//保证播放器单例
if(!MT.audio){
    MT.audio = new Audio();
}
MT.audio.src  = url;
MT.audio.play();
MT.audio.addEventListener("ended",function(){
    //播放完成,更新UI
},false);

2、判断是否支持flash,用flash播放
判断flash:

if (navigator.plugins && navigator.plugins.length && navigator.plugins['Shockwave Flash']) {
    return true;
} else if (navigator.mimeTypes && navigator.mimeTypes.length) {
    var mimeType = navigator.mimeTypes['application/x-shockwave-flash'];
    return mimeType && mimeType.enabledPlugin;
}

flash录音播放(as)核心代码:

import flash.external.*;
ExternalInterface.addCallback("playAudio",this,playAudio);
ExternalInterface.addCallback("stopAudio",this,stopAudio);
var mp3 = new Sound();
mp3.setVolume(300);
//播放结束
mp3.onSoundComplete=function(){
        //触发外部JS方法
	ExternalInterface.call("audioForFlash.trackEnded");
}
//播放音乐
function playAudio(url){
	mp3.stop();
	mp3.loadSound(url,true);
	mp3.onLoad = function(){
		mp3.start();
	}
}
//停止播放
function stopAudio(){
	mp3.stop();
}
setTimeout(function(){
	//提示外部加载完毕
	ExternalInterface.call("audioForFlash.loadStarted");
},100);

3、其它情况无法播放,提供链接下载

—————————————————-

android平台手机测试了几款,发现,有些能播放,有些不能播放(前提浏览器都装有flash插件)

经过一下午的折腾,总算解决问题了。

总结如下:

1、flash对象不能动态方式在后期append到dom,只能随页面一起加载

2、flash中调用到的外部js方法,必须出现在flash的对象之前(曾经在ie6中遇到类似情况)

3、flash对象只有在可见区域才能被激活,也就是说flash不能display:none,也不能在页面看不到的地方(如页面底部,需要滚动才能看到),不过可以用visibility:hidden;

前两个问题好办,第三个问题很诡异,现象总结如下:

3.1、页面很长,flash在底部,加载页面时候看不到,flash不会被激活

3.2、滚动页面,flash可见时候会继续被激活

3.3、继续滚动页面,flash不可见,flash中的动作中止(如录音播放一半中止)

解决方案

动态设置flash对象的position,使其在播放时候可见。

核心代码:

//在点击播放按钮,或者滚动页面时执行以下代码
document.getElementById("flash_box").style.top = 60 + document.documentElement.scrollTop  || 0 )+'px';
//用于“激活”页面
document.documentElement.scrollTop+=1;

注意后面那行代码,如果不通过这种方式手动激活页面,flash还是被认为不可见。

成果截图:

iphone访问web链接自动下载并安装程序

2011 十一月 24
by admin

核心其实是一个plist文件和一个itms-services的链接协议,通过字段的正确配置,就可以直接在iphone网页上安装app了。
链接示例:
<a href=”itms-services://?action=download-manifest&url=http://3g.momo.im/down/momomomo.plist”>安装移动momo</a>
plist文件示例:

<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=”1.0″>
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>http://3g.momo.im/down/momomomo.ipa</string>
</dict>
<dict>
<key>kind</key>
<string>display-image</string>
<key>needs-shine</key>
<true/>
<key>url</key>
<string>http://3g.momo.im/down/ICON.PNG</string>
</dict>
<dict>
<key>kind</key>
<string>full-size-image</string>
<key>url</key><string>http://3g.momo.im/down/ICON@2x.PNG</string>
</dict>
</array><key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>com.nd.momo</string>
<key>bundle-version</key>
<string>1.0.0</string>
<key>kind</key>
<string>software</string>
<key>subtitle</key>
<string>Apple</string>
<key>title</key>
<string>移动momo</string>
</dict>
</dict>
</array>
</dict>
</plist>

moTouch js 框架更新到 v0.02版,实现了常用dom及ajax操作

2011 十一月 17
by admin

针对momo触屏版的需要,写了一个精简版js框架,专用于支持html5选择器的项目,如momo 手机web触屏版。

接口规则与jquery保持一致,用过jquery的看了下面的DEMO一定觉得很熟悉。目前仅分享基础框架,只有240行代码,包括:ajax操作(get,post,getJSON,ajax)、最基本的dom(show,hide,hasClass,addClass,removeClass,replaceWith,remove…)操作等。当然和jquery一样,您可以随便通过 extend方法去无限扩展框架,打造适合自己的JS组件或者框架。

目前版本:v0.02
最后更新时间:2011-11-22
大小:15K,压缩后5K,gzip后3K

框架DEMO:http://jslover.com/wp-content/uploads/2011/11/motouch/demo.htm

源码:http://jslover.com/wp-content/uploads/2011/11/motouch/moTouch.js


//demo示例
(function ($) {
    //ajax get方法
    $.get('json_test.js', { r: Math.random() }, function (data) { alert(data) });

    // 支持任意扩展
    $.extend({
        alert: function (val) {
            alert(val);
        }
    });
    // 支持任意扩展
    $.fn.extend({
        newFunc: function () {
            alert('newFunc');
            return this;
        }
    });

    $.alert('这是扩展的方法');
    $('body').newFunc();

    // 获取对象
    var $div = $('div');
    //对象个数
    alert($div.length);
    //添加样式
    $div.addClass('class1');
    //替换节点
    $('img').replaceWith('不显示图片');
})(moTouch);

MOMO 手机WEB触屏版截图泄漏,即将开放,敬请期待

2011 十一月 8
by admin

无需安装也能跑的app,MOMO 手机WEB触屏版即将公开发布,敬请期待。

需要手机浏览器支持常见html5,css3特性。

另外,momo web、momo各平台app也将同期更新版本,敬请期待!

附地址:
iphone/android/webos访问
http://3g.momo.im (简化版)
http://3g.momo.im/scroll (完全版)

通过localStorage对脚本文件进行缓存,html5文件缓存的另类实现

2011 十一月 3
by admin

说到html5缓存,很自然就想到manifest,为了提高3g momo的体验,我们也特意尝试了这个,甚至做到了完全离线使用WEB页,像客户端一样,离线查询通讯录等。

不过,使用manifest的过程中,遇到了一个没法解决的问题:文件更新。理想状态,可以通过修改.manifest文件达到通知版本更新的效果,不过现实很不乐观,测试结果,在iphone的safari及pc chrome浏览器中,基本正常,修改.manifest文件后强制刷新两次页面就达到更新缓存文件的效果,至于为什么是2次,不想去纠结,至少它真能更新了。

在FF中,只能通过”工具-选项-脱机数据“删除缓存来达到更新效果,至于为什么更新.manifest起不到作用?我猜想.manifest文件也被缓存了吧,总之,FF上想用文件缓存又想随时通过代码更新,想都别想了。同样,在android机子(我用g6测试)上也是类似状况,甚至更恶劣,几乎快抓狂了。

查询了所有网上资源,几乎都是千篇一律,异想天开的理想主义,最全的一篇大概是这样:http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html。痛恨那些胡乱转载的门户,鄙视那些不经测试就贴代码的2B青年,特别指出,通过iframe页设置manifest的方式是不可取的,不知道那篇文章的作者是怎么测试的,总之目前版的浏览器是不支持这样缓存的。

——总之,为了兼容,我必须放弃manifest————————————–

于是,放弃“离线应用”,转向文件缓存,这样就容易多了,最终,决定将所有文件读取下来后通过localStorage对象以key-value形式存储,然后再通过eval执行脚本。

原理很简单,代码贴在后面,要注意的一点还是更新机制。

我设计的更新机制很简单:localStorage对象中存储最后更新的版本号,每次页面刷新时候与服务端的版本号变量进行比对,不等就更新,否则继续使用,当然在UI中也提供了手动更新的方法,确保随时对版本文件可控。

——-经常多平台测试,完全正常,随时可以更新———————————–

参考代码:这段代码挂在页面底部

//当前脚本版本号
var script_server_version = '0.3';
//待请求脚本队列
var script_list = ['/lib/lib.js', '/script/index.js', '/script/template.js'];

(function () {
    //异步获取文件
    function ajaxGet(url, callback) {
        var request = new XMLHttpRequest();
        if (!request) { return; }
        request.open("GET", url, true);
        request.onreadystatechange = function () {
            if (request.readyState == 4) {
                callback(request.responseText);
            }
        };
        request.send(null);
    }

    //临时变量
    var scriptCache = '';
    var index = 0;
    //循环加载
    function getScript() {
        ajaxGet(script_list[index] + '?v=' + script_server_version, function (data) {
            scriptCache += data;
            if (++index < script_list.length) {
                getScript();
            } else {
                //存入缓存
                localStorage['script_cache'] = scriptCache;
                //存入当前版本号
                localStorage['script_version'] = script_server_version || 0;
                setTimeout(function () {
                    //执行脚本
                    eval(scriptCache);
                }, 100);
            }
        });
    }
    //直接输出脚本
    function writeScript() {
        for (var i = 0; i < script_list.length; i++) {
            document.write('..输出脚本,被过滤了,各位自己实现..');
        }
    }
    //开始请求脚本
    try {
        //支持缓存
        if ('localStorage' in window) {
            //服务器保存的脚本版本,通过页面直接输出变量
            var version_server = script_server_version || 0;
            //本地版本号
            var version_local = localStorage['script_version'] || -1;
            //如果版本号不一致,或者不存在缓存
            if (version_server != version_local || !localStorage['script_cache']) {
                getScript();
            } else {
                //执行脚本
                setTimeout(function () {
                    eval(localStorage['script_cache']);
                }, 100);
            }
        } else {
            writeScript();
        }
    } catch (ee) {
        writeScript();
    }
})();

一个简易的HTML5绘图板,带重绘功能

2011 十月 31
by admin

html5的canvas对象和as3的绘图对象差不多,总结来说就是样式、moveTo、lineTo,当然,需要重绘功能,就要自己建立history堆栈。

功能很简单,html5 api很强大,简单几行就可以实现大多功能,在此基础上,可以通过拓展,设计线条样式、增加图形、文字等,甚至还能增加滤镜功能。

贴上demo,大家自己看吧,注意浏览器需要支持html5。 html5draw.htm

绘图板

//绘图板
function Drawbox(canvas) {
    this.canvas = canvas;
    this.context = this.canvas.getContext('2d');
    //线条宽度
    this.context.lineWidth = 2;
    //线条颜色
    this.context.strokeStyle = '#555';
    //线条圆角
    this.context.lineCap = "round";
    //状态
    this.drawing = false;
    //历史记录
    this.his = [];
    this.timeout_draw = 0;

}
Drawbox.prototype = {
    mousedown: function (e) {
        this.drawing = true;
        this.his.push({
            x: e.layerX
            , y: e.layerY

        });
    }
    , mouseup: function (e) {
        this.drawing = false;
        this.his.push({
            x: e.layerX
            , y: e.layerY
            //是否中止,鼠标放开时,记录状态,防止“连笔”
            , end: 1
        });
    }
    , mousemove: function (e) {
        var _this = this;
        if (_this.drawing) {
            //将坐标不断存入历史记录
            _this.his.push({
                x: e.layerX
                , y: e.layerY
            });
            _this.context.beginPath();
            var l = _this.his.length;
            if (!_this.his[l - 1].end) {
                _this.context.moveTo(_this.his[l - 2].x, _this.his[l - 2].y);
                _this.context.lineTo(_this.his[l - 1].x, _this.his[l - 1].y);
                _this.context.stroke();
            }
        }
    }
    , init: function () {
        var _this = this;
        _this.canvas.addEventListener('mousemove', function (e) { _this.mousemove(e) }, false);
        _this.canvas.addEventListener('mousedown', function (e) { _this.mousedown(e) }, false);
        _this.canvas.addEventListener('mouseup', function (e) { _this.mouseup(e) }, false);
    }
    //清空
    , clear: function (noClearHis) {
        var _this = this;
        clearTimeout(_this.timeout_draw);
        //清空
        _this.context.clearRect(0, 0, 3000, 3000);
        if (!noClearHis) {
            //清除历史记录
            _this.his.length = 0;
        }
    }
    //重绘
    , reDraw: function () {
        var _this = this;
        _this.clear(true);
        var i = 0;
        var length = _this.his.length;
        clearTimeout(_this.timeout_draw);
        if (length < 2) { return; }
        function draw() {
            if (!_this.his[i].end) {
                _this.context.moveTo(_this.his[i].x, _this.his[i].y);
                _this.context.lineTo(_this.his[i + 1].x, _this.his[i + 1].y);
                _this.context.stroke();
            }
            _this.timeout_draw = setTimeout(function () {
                if (i < length - 1) {
                    draw();
                }
            }, 10);
            ++i;
        }
        draw();
    }
    //导出PNG图片
    , toPng: function () {
        var url = this.canvas.toDataURL();
        if (document.getElementById("temp_img")) {
            document.getElementById("temp_img").src = url;
        } else {
            var img = document.createElement('img');
            img.id = "temp_img";
            img.src = url;
            document.body.appendChild(img);
        }
    }
};

var draw = new Drawbox(document.getElementsByTagName('canvas')[0]);
draw.init();

iphone webapp 隐藏地址栏(全屏)解决方案

2011 十月 24
by admin

核心代码:window.scrollTo(0, 1);

要注意的几个点:这个方法要在内容加载完成后执行,换句话浏览器内容的高度要超过浏览器窗口高度(出现‘滚动条’)才有效。

针对这个高度自适应的窗口(height:100%),得用特殊方式解决:

//强制让内容超过
$('#main').css("height",window.innerHeight+100);
window.scrollTo(0, 1);
//重置成新高度
$("#main").css("height",window.innerHeight);
//非常重要,用于兼容不同机型,防止浏览器窗口移动
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

另外,最后一行,用于阻止手动滚动页面

一条重要的代码用于兼容iscroll组件

2011 十月 24
by admin

document.addEventListener(‘touchmove‘, function (e) { e.preventDefault(); }, false);

对,就是这么简单一句,却非常重要。

在做momo web touch版的时候,android系统主要都是针对htc系列手机,转QA测试后,在索爱x8系列的手机中,出现BUG,浏览器会随着内容移动,导致iscroll组件出现异常。

iphone网页js接入rabbitmq长轮询中断的解决方案

2011 十月 20
by admin

问题环境:

1、iphone的safari浏览器,有个特点,在屏保或者最小化浏览器后,会自己暂停所有浏览器进程。

2、通过js接入rabbitmq进行长轮询,原理是保持一个永不间断的http请求,因为上面的问题,导致在最小化浏览器时候这个http请求会被暂停,导致服务端超时,造成了长轮询被迫中断。

解决方案:

1、改用websocket或者其它方式连接mq(不在本次讨论范围);

2、轮询,监听mq状态。

想实现状态监听就必须找到相关的接口,rabbitmq的js组件,找不到官方维护文档,没有api文档,没有注释,只好debug打log。最终找到了两个重要接口:

打开连接后会返回通道对象,这个对象有一个.alive 的属性,用于检测状态。

另外,有一个公共方法 .close(),用于关闭连接。

RabbitMQ.openChannel(function (c) {
//记录通道对象
MT.im.channel = c;
MT.im.queue_consume();
},{
debug: false
});
有了这两个接口,问题就解决了,最简单的方案:
//定时检查状态
,autoCheck:function(){
if(TM.im.intervalId){
clearInterval(TM.im.intervalId);
}
TM.im.intervalId = setInterval(function(){
try{
//检测状态
if(!MT.im.channel.alive){
//.close()方法不一定要执行,!.alive的时候基本可以确认已经是closed状态
MT.im.channel.close();
//重新开始建立查询
MT.im.query();
}
}catch(ee){}
},10000);
}
这个autoCheck方法,在ready以后执行,当然,在一些操作上,如切换tab等方法上带上这个方法,更能确保检测时时进行。
WordPress SEO fine-tune by Meta SEO Pack from Poradnik Webmastera