最近换了新公司,全部转移到了移动终端的开发上,所幸现在各个浏览器厂商进步的很快,更所幸不需要兼容UC等一众国内浏览器,所以各种CSS3新特性用的十分爽快。 由于之前没有大段时间去做移动端开发,现在全部投入进来之后,发现自己已经落后很多了,各种新特性完全不知道,现在将工作中遇到的一些值得记录的地方,记录在这里,随时更新。
###CSS部分
在css3中,可以使用box-sizing这个属性来定义盒模型宽度和高度的计算状态,举个栗子:
.a { box-sizing:border-box; width:500px; height:500px padding:100px; }
在这个情况下,a模块的宽度是500px。而不是100 + 500 + 100,这是因为设置了box-sizing:border-box的原因。这个属性还有其他几种值可选,分别是:content-box,inherit,initial,padding-box。
在绝大多数新版本的浏览器中,select元素的样式是可以随意设置的,但是右侧的小三角却没有办法通过background:none来去掉。在pc端,一般我们的做法就是直接用div去模拟这个select的动作,为了满足这个需求,我还曾写了cell-ui这个项目,结果当然也是挖了坑没填… 言归正传,在webkit内核的浏览器中,是可以通过-webkit-appearance: none;这个属性来将select右侧的小三角隐藏掉掉。
在移动端,由于手指操作的原因,很多<a>标签都被设置成block形式,以增大可点击的区域,但是可点击的区域比较多的话,就会比较容易出现误操作的现象,比如我碰到的问题就是本来是想点击页面中浮层的关闭按钮,结果浮层确实是关闭了,可是因为click事件的延迟性,关闭按钮下面的一个链接也会被点击到,这个时候就比较蛋疼了。 但是可以通过给可点击的链接设置pointer-events:none,这个属性,来使<a>链接暂时不可点击。
###js部分
在移动端,所有的动作都变成了touch相关,包括但不限于touchstart,touchend,touchmove,touchcancel,任何一个在屏幕上的动作,级别上都遵循touchstart->touchmove->touchend这个过程,所以绝大多数的事件绑定也需要绑定在这些事件上。
在移动端,还有一个事情是需要注意的,就是input或者textarea这种可输入的控件,在获取焦点时,会自动弹出软键盘。在最近做的一个需求中,要求在点击input框外的一个元素时,软键盘依然保持在展开状态,也就是说需要给input触发一个focus状态才行。
本来是想在给input框外的元素添加tap事件的回调时,给input添加focus事件,但是发现在很多手机上并不好使。 在这里解释一下tap这个事件,tap是zepto封装的一个事件,实现原理就是在touchstart和touchend都触发在同一元素上时,touchend结束时异步触发一个tap事件。按照道理来说,在这个时候触发一个input的focus事件,应该是可以使input获得焦点的,但是在iPhone上试了很多次,就是无法获得焦点,不知道是什么原因。后来的解决方案是在touchstart时,使input触发focus事件,结果就好了。具体的原理,还有待分析,但是在iphone和android下事件的触发时间是不一致的,在我的iphone中,点击一个input框外的元素,事件触发的顺序是:
// 代码
$('#input').bind('blur',
function () {
console.log('blur');
});
$('#input').bind('focus',
function () {
console.log('focus');
});
$('#other').bind('touchstart',
function () {
console.log('touchstart');
});
$('#other').bind('touchend',
function () {
console.log('touchend');
});
$('#other').bind('tap',
function () {
console.log('tap');
});
// iphone的结果是
// touchstart -> touchend -> tap ->blur
// 浏览器中模拟android的结果是
// touchstart -> blur -> touchend -> tap
可以看出来,触发的顺序是不一致的。模拟的android中的顺序,更接近我们所理解的顺序,iphone中疑似对事件做了优化,所以导致blur在tap之后才被触发。 接下来,我又做了个测试,添加了一行代码:
$('#input').bind('blur',
function () {
console.log('blur');
});
$('#input').bind('focus',
function () {
console.log('focus');
});
$('#other').bind('touchstart',
function () {
console.log('touchstart');
});
$('#other').bind('touchend',
function () {
console.log('touchend');
});
$('#other').bind('tap',
function () {
console.log('tap');
$('#input').focus();
});
// iphone的结果是:
// touchstart -> touchend -> tap -> blur
// 浏览器中模拟android的结果是
// touchstart -> blur -> touchend -> tap -> focus
可以看出来,iphone中本应该被触发的focus事件没有触发,可以被认定为已经被优化掉了,至此大概可以理解,为什么在tap中触发input的focus事件没有生效了。