最全移动Web开发教程小技巧经验
现在人手一部智能机,iPhone已经烂大街了,作为一个网站,一个独立的手机站必不可少,即使你使用的代码适配,很多小技巧你必须知道,这篇总结了一些移动Web开发教程小技巧经验,分享给大家!
本文主要收集一些移动Web开发中常见的问题和解决办法,在日常的工作中遇到新的问题会不定时更新到文章中。
屏蔽阴影
-webkit-appearance:none
亲测完美运行,可以同时屏蔽输入框怪异的内阴影,解决iOS下无法修改按钮样式,测试还发现一个小问题就是,加了上面的属性后,iOS下默认还是带有圆角的,不过可以使用 border-radius 属性修改。
Meta标签
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" />
这个想必大家都知道,当页面在手机上显示时,增加这个meta可以让页面强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览。
<meta content="telephone=no" name="format-detection" />
<meta content="email=no" name="format-detection" />
这两个属性分别对ios上自动识别电话和android上自动识别邮箱做了限制。
获取滚动条的值
window.scrollY
window.scrollX
桌面浏览器中想要获取滚动条的值是通过 document.scrollTop 和 document.scrollLeft 得到的,但在iOS中你会发现这两个属性是未定义的。
因为在iOS中没有滚动条的概念,在Android中通过这两个属性可以正常获取到滚动条的值,那么在iOS中我们该如何获取滚动条的值呢?就是上面两个属性,但是事实证明android也支持这属性,所以索性都用 woindow.scroll
。
禁止选择文本
-webkit-user-select:none
禁止用户选择文本,IOS 和 Android 都支持,基本不需要做兼容!
CSS 之 border-box
element{
width: 100%;
padding-left: 10px;
box-sizing:border-box;
-webkit-box-sizing:border-box;
border: 1px solid blue;
}
那我想要一个元素100%显示,又必须有一个固定的 padding-left/padding-right
,还有1px的边框,这样编写代码必然导致出现横向滚动条,这时候伟大的 CSS3 为我们提供了 box-sizing
属性,可以将元素填充、间距和边框一起算在元素的尺寸里面。
CSS3多文本换行:
p{
overflow : hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
Webkit支持一个名为 -webkit-line-clamp
的属性,也就是说这个属性并不是标准的一部分,可能是Webkit内部使用的,或者被弃用的属性。需要注意的是 display
需要设置成 box
,-webkit-line-clamp
表示需要显示几行。
Retina屏幕高清图片
selector {
background-image: url(no-image-set.png);
background: image-set(url(foo-lowres.png) 1x,url(foo-highres.png) 2x) center;
}
image-set的语法,类似于不同的文本,图像也会显示成不同的:
- 不支持
image-set
:在不支持image-set
的浏览器下,他会支持background-image
图像,也就是说不支持image-set
的浏览器下,他们解析background-image
中的背景图像; - 支持
image-set
:如果你的浏览器支持image-sete
,而且是普通显屏下,此时浏览器会选择image-set
中的@1x
背景图像; - Retina屏幕下的
image-set
:如果你的浏览器支持image-set
,而且是在Retina屏幕下,此时浏览器会选择image-set
中的@2x
背景图像。
html5重力感应事件
if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion',deviceMotionHandler, false);
}
var speed = 30;//speed
var x = y = z = lastX = lastY = lastZ = 0;
function deviceMotionHandler(eventData) {
var acceleration =event.accelerationIncludingGravity;
x = acceleration.x;
y = acceleration.y;
z = acceleration.z;
if(Math.abs(x-lastX) > speed || Math.abs(y-lastY) > speed || Math.abs(z-lastZ) > speed) {
//简单的摇一摇触发代码
alert(1);
}
lastX = x;
lastY = y;
lastZ = z;
}
关于 deviceMotionEvent
是HTML5新增的事件,用来检测手机重力感应效果。
移动端Touch事件
- touchstart //当手指接触屏幕时触发
- touchmove //当已经接触屏幕的手指开始移动后触发
- touchend //当手指离开屏幕时触发
- touchcancel //当某种touch事件非正常结束时触发
这4个事件的触发顺序为: touchstart -> touchmove -> touchend -> touchcancel
对于某些android系统touch的bug: 比如手指在屏幕由上向下拖动页面时,理论上是会触发 一个 touchstart
,很多次 touchmove
,和最终的 touchend
,可是在android 4.0上,touchmove
只被触发一次,触发时间和 touchstart
差不多,而 touchend
直接没有被触发。
这是一个非常严重的bug,在 google Issue 已有不少人提出 ,这个很蛋疼的bug是在模拟下拉刷新是遇到的尤其当 touchmove
的dom节点数量变多时比出现,当时解决办法就是用 settimeout
来稀释 touchmove
。
单击延迟
Click 事件因为要等待双击确认,会有 300ms
的延迟,体验并不是很好。 开发者大多数会使用封装的 tap 事件来代替click 事件,所谓的 tap 事件由 touchstart 事件 + touchmove 判断 + touchend 事件封装组成。
IOS里面fixed的文本框焦点居中
<!DOCTYPE html>
<head>
<style>
input {
position:fixed;
top:0;left:0;
}
</style>
</head>
<body>
<div class="header">
<form action="">
<label>Testfield: <input type="text" /></label>
</form>
</div>
</body>
</html>
在IOS里面,当一个文本框的样式为 fixed
时候,如果这个文本框获得焦点,它的位置就会乱掉,由于ios里面做了自适应居中,这个 fixed
的文本框会跑到页面中间。类似:里面,当一个文本框的样式为 fixed
时候,如果这个文本框获得焦点,它的位置就会乱掉,由于ios里面做了自适应居中,这个 fixed
的文本框会跑到页面中间。
解决办法有两个:
可以在文本框获得焦点的时候将 fixed
改为 absolute
,失去焦点时在改回 fixed
,但是这样会让屏幕有上下滑动的体验不太好。
.fixfixed {
position:absolute;
}
$(document)
.on('focus', 'input', function(e) {
$this.addClass('fixfixed');
})
.on('blur', 'input', function(e) {
$this.removeClass('fixfixed');
});
还有一种就是用一个假的 fixed
的文本框放在页面顶部,一个 absolute
的文本框隐藏在页面顶部,当 fixed
的文本框获得焦点时候将其隐藏,然后显示 absolute
的文本框,当失去焦点时,在把 absolute
的文本框隐藏,fixed
的文本框显示。
.fixfixed {
position:absolute;
}
$(document)
.on('focus', 'input', function(e) {
$absolute..show();
$this.hide();
})
.on('blur', 'input', function(e) {
$fixed..show();
$this.hide();
});
最后一种就是顶部的input不参与滚动,只让其下面滚动。
position:sticky
position:sticky
是一个新的css3属性,它的表现类似 position:relative
和 position:fixed
的合体,在目标区域在屏幕中可见时,它的行为就像 position:relative
; 而当页面滚动超出目标区域时,它的表现就像 position:fixed
,它会固定在目标位置。
.sticky {
position: -webkit-sticky;
position:sticky;
top: 15px;
}
浏览器兼容性: 由于这是一个全新的属性,以至于到现在都没有一个规范,W3C也刚刚开始讨论它,而现在只有webkit nightly版本和chrome 开发版(Chrome 23.0.1247.0+ Canary)才开始支持它。 另外需要注意的是,如果同时定义了 left
和 right
值,那么left生效,right会无效,同样,同时定义了top和bottom,top赢~~ 移动端点透事件 简单的说,由于在移动端我们经常会使用tap(touchstart)事件来替换掉click事件,那么就会有一种场景是:
<div id="mengceng"></div>
<a href="www.qq.com">www.qq.com</a>
div是绝对定位的蒙层z-index高于a,而a标签是页面中的一个链接,我们给div绑定tap事件:
$('#mengceng').on('tap',function(){
$('#mengceng').hide();
});
我们点击蒙层时 div正常消失,但是当我们在a标签上点击蒙层时,发现a链接被触发,这就是所谓的点透事件。 原因: touchstart 早于 touchend 早于 click。亦即click的触发是有延迟的,这个时间大概在300ms左右,也就是说我们tap触发之后蒙层隐藏,此时click还没有触发,300ms之后由于蒙层隐藏,我们的click触发到了下面的a链接上。 解决办法: 1 尽量都使用touch事件来替换click事件。 2 阻止a链接的click的preventDefault base64编码图片替换url图片 u在移动端,网络请求是很珍贵的资源,尤其在2g或者3g网络下,所以能不发请求的资源都尽量不要发,对于一些小图片icon之类的,可以将图片用base64编码,来减少网络请求。
手机拍照和上传图片
<input type="file" />
的 accept
属性
<!-- 选择照片 -->
<input type=file accept="image/*">
<!-- 选择视频 -->
<input type=file accept="video/*">
动画效果时开启硬件加速 我们在制作动画效果时经常会想要改版元素的top或者left来让元素动起来,在pc端还好但是移动端就会有较大的卡顿感,这么我们需要使用css3的 transform: translate3d;
来替换, 此效果可以让浏览器开启gpu加速,渲染更流畅,但是笔着实验时在ios上体验良好,但在一些低端android机型可能会出现意想不到的效果。
快速回弹滚动
在iOS上如果你想让一个元素拥有像 Native 的滚动效果,你可以这样做:
.div {
overflow: auto;
-webkit-overflow-scrolling: touch;
}
经笔着测试,此效果在不同的ios系统表现不一致, 对于局部滚动,ios8以上,不加此效果,滚动的超级慢,ios8一下,不加此效果,滚动还算比较流畅 对于body滚动,ios8以上,不加此效果同样拥有弹性滚动效果。
IOS和Android局部滚动时隐藏原生滚动条
Android
::-webkit-scrollbar{
opacity: 0;
}
IOS 使用一个稍微高一些div包裹住这个有滚动条的div然后设置overflow:hidden挡住之
.wrap{
height: 100px;
overflow: hidden;
}
.box{
width: 100%;
height: -webkit-calc(100% + 5px);
overflow-x: auto;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
}
<div class="wrap">
<div class="box"></div>
</div>
设置placeholder时候 focus时候文字没有隐藏
input:focus::-webkit-input-placeholder{
opacity: 0;
}
background-image和image的加载区别
在网页加载的过程中,以CSS背景图存在的图片 background-image
会等到结构加载完成(网页的内容全部显示以后)才开始加载,而HTML中的标签 <img/>
是网页结构(内容)的一部分会在加载结构的过程中加载,换句话讲,网页会先加载标签 <img/>
的内容,再加载背景图片 background-image
。
如果你用引入了一个很大的图片,那么在这个图片下载完成之前,<img/>
后的内容都不会显示。而如果用CSS来引入同样的图片,网页结构和内容加载完成之后,才开始加载背景图片,不会影响你浏览网页内容。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论