-webkit-overflow-scrolling: touch; 隐藏滚动条

如果你不知道 -webkit-overflow-scrolling: touch; 是什么意思,它是用在移动端 webkit 内核浏览器的一个滚动条效果,通常我们的页面滚动(body 会默认采用这种方案无需代码声明)当手指触摸滑动时,它是不会以一种惯性,带回弹效果的滚动,而这段代码即是让它拥有这种像 App 一样的效果(很显然它是非常有必要的,完全可以全局的变成默认行为),历史就不写了。

在我使用这段代码的时候它随即带来了一个问题,-webkit-overflow-scrolling: touch; 所带来的滚动条在未滚动的时候是隐藏状态,而当手指尝试去滑动滚动条就会显示出来,然而这个控件的样式并非像桌面浏览器可以自定义,也就是说无法隐藏。

<nav>
    <ul>
        <li>菜单</li>
        <li>菜单</li>
        <li>菜单</li>
    </ul>
</nav>

或者你可能用的是 div 而不是 nav,这里并没有关系。首先 li 层也没有关系。

那么你设计的滚动部分可能在 ul,假设你的 ul 设定高度为 40px,并且隐藏了纵向(Y)滚动条,且允许横向(X)滚动;至此 nav 可能并没有做什么设定,又或者你也对它设定了一些参数。

隐藏这个 ul 所产生的横向滚动条的方法是:将 ul 的高度提升为 51px(增加 11px 左右),而后锁定 nav 的高度为 40px,并且对 nav 也做 x y 轴的滚动条隐藏(让超出的 11px 不会产生纵向滚动,而滚动条则位于 overflow-y: hidden; 所遮挡的部分,这样就达到看不见的目的了)。

对于自动变化高度的横向滚动条暂时好像这个方案并不能解决,不过一般都是固定高度吧?

另外一个小地方,如果你把 -webkit-overflow-scrolling: touch; 定义在了 body 可能出现标签页白屏的问题,所以你应该这样做:

nav, div, ul { -webkit-overflow-scrolling: touch; }

不要定义在 body(body 和 html 会自动带有这种效果),而定义在,你的滚动条多半只可能出现在的几种类型,例如 nav div 和 ul。

目前为止 iOS 8.4 中的 Safari 不会白屏,但其它浏览器如果定义在 body 均会白掉。

在demo的导航部分,可以查看-webkit-overflow-scrolling的效果。
猛击demo ☻

移动端根据滑动的角度决定滑动方向

大家都知道,划动都有角度问题,比如 45 度方向滑动手机,要计算出它的方向问题。HTML5 提供的滑动事件,只能读取到起点和终点坐标,需要计算角度,然后根据角度推算出方向。

解决方案

1、滑动屏幕事件使用 HTML5 的 touchstart 滑动开始事件和 touchend 滑动结束事件。

2、方向的判断,以起点做平面坐标系,与终点连线做直线,直线与x正半轴计算角度;我们以45度角为方向分割线,如:只要滑动角度大于等于45度且小于135度,则判断它方向为向上滑。

3、使用 Math.atan2 来计算起点与终点形成的直线角度。

4、仔细对比标准坐标系与屏幕坐标系,我们发现,标准坐标系,上半轴为负值,要实现转换,只需要调换Y坐标起点与终于位置即可。

附上代码:

继续阅读 移动端根据滑动的角度决定滑动方向

H5焦点图

焦点图算是最基础的控件了,很多地方都在用,在网上找了一圈,没发现原生JS的,都是各种框架和库,正好自己写一个,发现里面小门道还挺多的,想要体验好,各种细节都要去抠才行:

1、大家都知道,一般翻页都是滑动距离超过 50% 才翻页,但如果快速滑动,即使滑动距离很短,也是可以翻页的,

这里就需要记录滑动开始的时间和滑动结束的时间,还要记录滑动的距离,设定一个范围值就ok,我设的是滑动耗时在150毫秒以下,距离在60以上,切换焦点图。

2、手机滑动焦点图,方向肯定不是很标准的横或竖,左或右。

所以呢,这里就需要计算滑动的方向,也就是角度,根据角度来判断往前翻,还是往后翻,为了体验好,例如大于-45度并且小于45度的,都算往右滑动,查看详细说明文章

3、体验好的焦点图,都是可以无限循环翻页的。

实现的方式也比较取巧,首先要克隆第一张图,并插入到父节点的最后,当翻到最后一页,再往后翻的话,就会翻到克隆的这一页,然后如果再往后翻,当 touchstart 刚触发的时候,会把图重置到第一幅图(第一和最后的图都一样,所以不会察觉到),这样,便实现了循环。如果要从第一幅图,往前滑动(从 dom 节点上看,第一幅图前面是克隆的图),就把 transform 的值,直接设成真实的最后一幅图的值,就行了。

4、仔细体验一下,当你在滑动焦点图的时候,页面是无法上下滚动的。在页面上下滚动的时候,你又无法滑动焦点图。

这需要在滑动的时候设置一个开关变量,来控制 touchmove 的时候,是否执行代码,还要 touchmove 的时候阻止浏览器默认事件 event.stopPropagation(),来实现滑动焦点图的时候,页面无法上下滚动;

前面说过了,要通过计算滑动的角度,来分出4个方向,上下左右。只有左右两个方向,会执行 touchmove 的代码,页面会滚动,上下两个方向不执行代码,页面不滚动,也就实现了页面上下滚动,无法滑动焦点图。

继续阅读 H5焦点图

一劳永逸,解决移动WEB布局问题

很早以前做移动 WEB 布局的时候,要适应各种分辨率的移动设备,把与元素尺寸有关的css,如 width, height, line-height, margin, padding 等都以 rem 作为单位,这样页面在不同设备下就能保持一致的网页布局,响应式设计不就应该是这么干的吗?但是从工作量和复杂度方面来考虑,它有以下几个不足:

(1)假设一个 .item 类在所有设备下的 width 都是 3.4rem,但在不同分辨率下的实际像素是不一样的,所以在有些分辨率下,界面效果不一定合适,有可能太宽,有可能太窄,这时候就要对 width 进行调整,那么就需要针对 .item 写媒介查询的代码,为该分辨率重新设计一个rem值。然而 css 又有很多跟尺寸相关的属性,哪个属性在哪个分辨率范围不合适都是不定的,最后会导致要写很多的媒介查询才能适配所有设备,而且在写的时候rem都得根据某个分辨率 html 的 font-size 去算,这个计算可不见得每次都那么容易,比如 40px / 23.5px,这个rem值口算不出来吧!由此可见这其中的麻烦有多少。

(2)设计稿都是以分辨率来标明尺寸的,前端在根据设计稿里各个元素的像素尺寸转换为rem时,该以哪个font-size为准呢?这需要去写才能知道
正是因为以上提到的一些不足,我觉得这种适配方式不是特别好,写起来太麻烦。为了完成工作,我们需要找寻更简单更有效率的方法。

有些 web app 不一定很复杂,用简单的方法也行,就是高度固定,宽度自适应,然后用百分比布局,这是一种典型的弹性布局,关键元素高宽和位置都不变,只有容器元素在做伸缩变换。对于这类 app,记住一个开发原则就好:文字流式,控件弹性,图片等比缩放。

但这种布局也有很多问题,举例来说,因为现在很多设计稿是根据 iphone6 的尺寸来的,而 iphon6 设备宽的逻辑的像素是375px,而 iphone4 的逻辑像素是 320 个像素,所以如果你根据设计稿做出来的东西,在 iphone4 里面可能显示不下,而且高像素的设备用起来真的很难看。。。。下面介绍个简单的方法,一劳永逸解决布局问题:)

分享个简单的解决办法:

先来看看网易在不同分辨率下,呈现的效果:

1 继续阅读 一劳永逸,解决移动WEB布局问题

自己做个网易新闻:)

一直很喜欢网易的APP,体验都很棒,也很精致,特别是网易新闻,更是天天要看啊,网页版做的也很棒,自己也想做个试试,当然了,自己做一个体验一定要跟网易一样棒才行,而且这个客户端里面的很多功能,其实在做其他项目的时候,也都用的上,就当练练手了!

里面有很多小坑和小体验,我也会慢慢更新到博客里,跟大家分享经验:)

TIPS:请用手机访问,或用chrome移动端调试模式浏览

猛击demo ☻

targetTouches、touches、changedTouches的具体区别

  • touches: 当前屏幕上所有触摸点的集合列表
  • targetTouches:  绑定事件的那个结点上的触摸点的集合列表
  • changedTouches:  触发事件时改变的触摸点的集合

举例来说,比如div1, div2只有div2绑定了touchstart事件,第一次放下一个手指在div2上,触发了touchstart事件,这个时候,三个集合的内容是一样的,都包含这个手指的touch,然后,再放下两个手指一个在div1上,一个在div2上,这个时候又会触发事件,但changedTouches里面只包含第二个第三个手指的信息,因为第一个没有发生变化,而targetTouches包含的是在第一个手指和第三个在div2上的手指集合,touches包含屏幕上所有手指的信息,也就是三个手指。

为了方便记忆,做了个图:

touch

用CSS3开启GPU硬件加速来提升网站的动画渲染性能

CSS3为咱们开发动画效果大大提升了效率,但有些动画效果,如果涉及的DOM元素比较多,会发现有“卡卡”的感觉,为动画DOM元素添加CSS3样式 -webkit-transform:transition3d(0,0,0)  -webkit-transform:translateZ(0) ,这两个属性都会开启GPU硬件加速模式,从而让浏览器在渲染动画时从CPU转向GPU,其实说白了这是一个小伎俩,也可以算是一个Hack, -webkit-transform:transition3d 和 -webkit-transform:translateZ 其实是为了渲染3D样式,但我们设置值为0后,并没有真正使用3D效果,但浏览器却因此开启了GPU硬件加速模式。

这种GPU硬件加速在当今PC机及移动设备上都已普及,在移动端的性能提升是相当显著地,所以建议大家在做动画时可以尝试一下开启GPU硬件加速。

当然也可以这样开启所有浏览器的GPU硬件加速:

webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
或者
webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
-o-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);

TIPS:通过 -webkit-transform:transition3d/translateZ 开启GPU硬件加速之后,有些时候可能会导致浏览器频繁闪烁或抖动,可以尝试以下办法解决之:

-webkit-backface-visibility:hidden;
-webkit-perspective:1000;

整理:目前移动端部分问题汇总

伪类 :active 生效

要CSS伪类 :active 生效,只需要给 document 绑定 touchstarttouchend 事件

<style>
a {
  color: #000;
}
a:active {
  color: #fff;
}
</style>
<a herf=foo >bar</a>
<script>
  document.addEventListener('touchstart',function(){},false);
</script>

消除 transition 闪屏

两个方法

-webkit-transform-style: preserve-3d;
/*设置内嵌的元素在 3D 空间如何呈现:保留 3D*/
-webkit-backface-visibility: hidden;
/*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/

消除 IE10 里面的那个叉号

input:-ms-clear{display:none;}

来源出处:http://msdn.microsoft.com/en-us/library/windows/apps/hh767361.aspx

继续阅读 整理:目前移动端部分问题汇总

HTML5音乐播放器(五):同步显示歌词

好久没更新博客了,真是罪过,老偷懒,鄙视下自己,这两天把歌词同步显示的功能弄完了,先来说说原理:

1.ajax获取歌词文件(lrc文件)。

2.用正则分别去过滤出歌词和歌词前面对应的时间,存入数组。

[ti:很难]
[ar:张震岳]
[al:OK]
[by:]
[00:15.79]又一天的一个晴天
[00:19.07]阳光印在这张旧沙发
[00:22.96]躺下来 闭上眼
[00:25.11]恍然不知寂寞 枕着蔓延
.....
//获取歌词内容
lrcVal = xmlhttp.responseText.replace(/[dd:dd.dd]/g,"");
lrcArray = lrcVal.split("n");

//歌曲名
lrcArray[0].replace(/[ww:(.*?)]/g,function(){
    musicName = arguments[1] || "暂无";
});

//歌手
lrcArray[1].replace(/[ww:(.*?)]/g,function(){
    singer = arguments[1] || "暂无";
});

//获取歌词时间轴
xmlhttp.responseText.replace(/[(d*):(d*)([.|:]d*)]/g,function(){
    var min = arguments[1] | 0, //分
    sec = arguments[2] | 0, //秒
    realMin = min * 60 + sec; //计算总秒数

    lrcTimeArray.push(realMin);
});

继续阅读 HTML5音乐播放器(五):同步显示歌词

HTML5音乐播放器(四):播放列表与播放方式

发现播放列表和播放方式切换两个功能是连在一起的,单独一个拿出来说不太合适,所以就都一块弄完了。废话不多说,进入主题,功能的逻辑我是这么设计的:

把整个歌曲文件的信息都写在 json 文件里,获取并生成播放列表。当播放歌曲时,系统会生成当前播放歌曲的引索值(例如:1,2,表示第二张专辑的第三首歌,这个很重要,歌曲切换都是基于这个引索值的),当要播放下一曲时,系统会根据当前是什么播放方式(列表循环,单曲循环,随机播放,顺序播放),生成新的引索值,然后通知播放器,下一首该怎么播放,是随机,还是循环,还是播放结束。

这部分代码不难,主要是要弄清楚整个流程应该是个什么方式,代码我就不贴了,demo 里都有,注释也都比较全。我描绘一下歌曲的播放流程,并写出它用到的函数,我想可能这种方法比较容易讲清楚:)

首先,我们要打开专辑列表,在打开的同时,生成专辑列表:

//---------------------------------------------------【功能:打开&关闭专辑列表】
MUSICENGINE.prototype.albumLists = function(){ ... };

//---------------------------------------------------【功能:生成专辑列表】
MUSICENGINE.prototype.formatAlbumLists = function(){ ... };

这时,可以播放了,我们可以双击专辑,打开专辑内的歌曲列表:

//---------------------------------------------------【双击专辑生成歌曲列表】
function formatInAlbumLists(song,AlbumName){ ... }

继续阅读 HTML5音乐播放器(四):播放列表与播放方式