小tip: 微博新版查看大图前后浏览的另外一种实现

这篇文章发布于 2013年05月17日,星期五,15:17,归类于 JS实例。 阅读 79162 次, 今日 6 次 25 条评论

 

一、新浪微博新版查看大图

你说我是先讲些废话呢还是讲些废话呢~~

搜索“新版微博查看大图”,结果前三如下:
网友对新版新浪微博查看大图的吐槽

其实这种效果,我在人人先见到,然后贴吧啊,还有我不使用的QQ空间等……按照我以往的经验,估计是从老美哪个网站copy过来的,然后,A闯红灯,B闯红灯,C也闯红灯,此时D觉得自己不闯红灯就不正常,于是也朝着红色的方向大步夺去。

数据上的好与不好,我不是专业的,随便乱说会烂舌头的。从个人感性认识上,微博似乎多了一件饰品。
永远都差一件饰品

青菜萝卜各有所爱,复杂与丰富也是一种气质,也会有人喜欢。

虽说事不关已高高挂起,微博是死是活我静观其变即可,但人在江湖身不由已,微博的产品以及开发人员必须有说不出的苦,甚至如下面的卡卡西般焦虑,因此,对于新的改版,我是大大的支持,奋力前进吧!
焦虑的卡卡西

//zxx: 看到木有,我并不是只会黑渣浪。

开头的废话到此,回到自己真正感兴趣的技术,对大围脖大图片大浏览的前后浏览感兴趣(图片左半边左箭头,右半边右箭头,见下截图):
微博大图查看左右箭头

经过查看,发现(90%+的确定),左右半区手形的变化是通过JS判断鼠标在图片的左半区还是右半区实现的,图片的垂直以及水平居中也是通过JS计算得到的。

这两点我都想吐槽:
1. JS判断鼠标在图片左半球还是右半区,势必要使用mousemove事件,经查阅,IE外的浏览器似乎不能直接获得鼠标相对于引起事件的对象的坐标,因此,还要一番额外计算,似乎还要与外部容器尺寸做比对,元素尺寸多半使用clientWidth,重绘触发,…… 其实性能的那点差异,容我IE6下观摩下,30秒后,终于看到界面啦,鼓掌!!然后是这个……一顿汗哦~~
IE6浏览器不支持的提示

不过应该要致敬的!

其实性能那点差异对于用户而言(尤其把IE6踢掉了),远不会达到100ms这个用户无法忍受的顿感时间的。因此,该实现主要问题在于实现的复杂,伤脑细胞,耗费时间,无论开发以及调试,因此,加班可能就少不了。

其实,我觉得,此功能实现的前辈肯定知道我这里想要实现的方法(层覆盖),但是,出于用户的考虑——喜欢右键存图等,这里使用了这种原图暴露在最上层的实现。

2. 我们都知道CSS是可以实现图片的水平以及居中效果的,从回流的角度讲(HTML变化了)(opacity透明度变化似乎不算),这里图片使用绝对定位是正确的选择;但是,考虑到,本身整个弹出层固定定位/绝对定位,所谓的回流非常有限(回流与DOM深度关系大大),因此,此处图片绝对定位,JS计算margin负偏移其实跟纯CSS实现水平垂直居中而言要逊色一点。

二、新人也能实现的实现方法

对于很多与页面打交道的前端而言,对CSS的熟悉要大于对JS的了解。因此,对于大多数同行而言,一个交互要想简单易实现就要充分发挥CSS/HTML的潜力,有的功能JS上百行的,如果你CSS处理得足够精致,JS可能就寥寥数行,实现的结果说不定会更甚一筹。当然,如果你的CSS纯粹就是会写写页面这种半吊子水平,多半上述对你而言只是美好理想,除非……你去让留几手来个惊世的点评,或者你对下面的内容的阅读与理解不是打马虎眼。不是开玩笑,一点一点沉寂的不断的积累,总会产生质变的。//zxx: 对了,也不能过分沉寂,只有技术是面不到好工作,泡不到好妹子的,能说会道为人处事的能力也很重要~~

左右半区的判断我们交给CSS/HTML完成,原理如下,一目了然:
左右半区覆盖点击原理

假设左边覆盖层的类名是prev,右边的覆盖层是next,父容器position:realtive,考虑到父容器的高度不定或以后潜在的尺寸变动性,我们要自适应处理,于是有如下CSS代码:

.prev, .next{
    /* 50%自适应于父容器 */
    width:50%;
    /* IE6下top:0; bottom:0 无法高度100%自适应,使用个超级高度,总归会100%显示的 */
    _height:2000px;
    /* 据说IE6/IE7下空的绝对定位层会镂空,使用个空背景意思下,使可点击 */
    background-image:url(about:blank);
    position:absolute;
    /* IE7+以及其他浏览器高度100%与父容器 */
    top:0; bottom:0;
}
/* 下面是手型以及左右定位 */
.prev{cursor:url(pic_prev.cur), auto; left:0;}
.next{cursor:url(pic_next.cur), auto; right:0;}

对应的HTML其实老简单了,为:

<div class="box">                	
    <s class="prev" title="上一张"></s>
    <s class="next" title="下一张"></s>
    <img src="mm1.jpg" />
</div> 

这种实现的好处除了些许的性能提高,节省了不少JS代码以及脑细胞外,我们还可以增加title属性,通过动态改变,告诉用户是否已经是最后一张图片了,一定程度上提高了用户体验。不过,金无足赤人无完人,此方法有个比较致命的影响体验的地方,就是,我们无法:右键-图片另存为|复制图片地址|……等浏览器相关的图片操作,因为我们右键的实际是覆盖层。

要修复这个问题并不难,右键上下文菜单为contextmenu事件,在IE6+, FireFox以及Chrome浏览器中,contextmenu事件都是紧随mouseup事件之后触发的。因此,我们只要在mouseup事件中让覆盖层隐藏,然后随即而来的contextmenu事件的目标元素就是下面的图片了,代码示意如下:

element.onmouseup = function(event) {
    /* 都懂的,兼容处理 */
    event = event || window.event;

    var target = this;
    /* 如果是右键或者包含右键点击 */
    if (/^2|6|4|7$/.test(event.button)) {
        target.style.visibility = "hidden";
        /* 小小定时器,正好跳过contextmenu事件 */
        setTimeout(function() { target.style.visibility = "visible";}, 16);            
    }        
};        

您可以狠狠地点击这里:覆盖层实现的前一张后一张切换效果demo

IE6下右键存图功能的实现

其他说明:
1. window下是Safari浏览器中,上下文菜单是紧随mousedown事件后触发的,而不是mouseup,如果您也想兼容此浏览器,需要多做点判断处理。我个人建议是,忽略之,除非Mac下也是如此。

2. CSS实现图片的垂直居中等已经嚼得太烂了,这里不再叙述。

3. demo共5张图片浏览。代码实现并不具有太多实用性,仅供参考,知其原理即可。

三、最后再唠叨点什么

若沉思、略悲伤我比较钦佩那些非常优秀的设计师,做的东西确实很赞!我也很钦佩那些语言算法很厉害的开发者,逻辑思维相当的强大!但是,我非常不屑那些以纯语言标准来评判前端优秀与否的人。很多前端是从后台过来的,我不清楚他们做前端的动机是什么,可能本身混不下去,觉得前端好欺负;或者是觉得前端更有前途,比较好混饭吃;或者是公司没人,自己顶上,顶着顶着就上了。因此,其思维或侧重更偏向于程序这边,在他们看来,如果你算法不懂、语言底层不了解,做开发难有大成。这种定律适用于纯开发性质的,你用C++写软件的,或者做JS底层的等。但是,对于前端这个职业,鉴于其复杂性、跨越性、职称难以鉴定性,这种判断我是很不屑的。

就PC网页端而言,我们制作的页面本身就是依附在浏览器中的,如果你是开发制作浏览器的,必须的,算法、底层等势必要了解;但是,我们只是在浏览器中折腾东西。实际本质上,跟在photoshop中美化图片没什么区别。要看到最终的目的是实现用户友好、节省成本的网页。对于大部分的网页而言,CSS/HTML绝对是绝大多数,所谓的JS交互,不过尔尔,用不上什么面向对象思想,用不到什么继承,像jQuery如此臃肿的东西显然也是没必要的。如果你不使用JS就能兼容实现所有想要的效果,没有哪个傻逼会因为你不会JS说你不是优秀的前端的。但是,实际上,很多人会因为你JS不擅长,就认为你前端也就那样。于是,“7级的JS+3级的CSS”就会认为“9级的CSS水平+3级的JS”没有自己牛逼。

看看,本文的展示,左右区域判断、图片垂直水平居中实现等,10分钟的CSS工作时间至少PK了20分钟的JS工作时间,还不算后期维护等。几乎同样的效果,你说,是JS主驱动的人优秀呢,还是CSS主驱动的人优秀?

这个问题其实是个坑,无论回答哪个都是不妥的。应该说,能够采用最优的方式实现我们想要效果的才是最优秀的前端。因此,那些有着所谓程序员自我良好感觉的人千万不要觉得页面仔们没什么技术含量,说不定,你正在被偷笑呢!——这个傻逼,明明几行CSS就可以实现的选项卡效果,这丫的居然写了上百行JS代码,笑屎了~~~

纯粹语言层面牛逼的人不见得是好前端,CSS/JS等各方面游刃有余的才能得心应手。善用软件的不见得比开发软件的逊,您说是吧,马云老师!

(本篇完)

分享到:


发表评论(目前25 条评论)

  1. tracy说道:

    妥妥滴被鑫哥圈粉啦~

  2. peter说道:

    element.onmouseup = function(event) {
    /* 都懂的,兼容处理 */
    event = event || window.event;

    var target = this;

    if (/^2|6|4|7$/.test(event.button)) {
    target.style.visibility = “hidden”;
    /* 小小定时器,正好跳过contextmenu事件 */
    setTimeout(function() { target.style.visibility = “visible”;}, 16);
    }
    };

    请问这里的if (/^2|6|4|7$/.test(event.button)) 2|6|4|7这几个数字和后面的event.button是什么意思啊?

  3. 呛咚呛说道:

    喜欢最后的唠叨

  4. 阿沈说道:

    当用户点击过快的时候,火狐浏览器会算作双击,然后图片就是被选中的状态,那种发淡淡的蓝光的覆盖层,影响体验。所以给覆盖层再加一句-moz-user-select:none;就完爆微博原有效果啦。

  5. 巴萨最强说道:

    这个是我常用的

  6. 阿牛说道:

    用定位来做图集翻页的还是比较多的。但是做到运用这种方法并且实现保存图片的就很少了 这里是第一次看到 楼主给力

  7. @陶子吃鱼儿说道:

    思路很好!
    纠正一个关于右键菜单触发时机的小错误:mac系统下所有浏览器(其实也包括所有应用程序)的右键菜单都是在mousedown之后触发的,因此上述代码对于操作系统的判断无法省略

  8. sss说道:

    微博js去搞居中,真心不想吐槽了

  9. cindy1009说道:

    大侠的唠叨很给力啊

  10. Gago说道:

    我也是采用的这种方法,两边,一边一个透明div搞定。但要注意z-index

  11. 玉面小飞鱼说道:

    ^_^“但是,实际上,很多人会因为你JS不擅长,就认为你前端也就那样”

    这篇文章CSS大战JS很给力。

    setTimeout(function() { target.style.visibility = “visible”;}, 16);

    16是自己拍脑袋得到的?

    • 张 鑫旭说道:

      @玉面小飞鱼 据说低版本IE浏览器setTimeout最小时间的瓶颈就是16毫秒~~

      • 玉面小飞鱼说道:

        我有个疑问想问问你,经常看到有人在讨论css各种选择器以及js的一些方法的效率问题,我的疑问是用什么指标来评判这些效率的高低呢?有些人会在文章里面标明用某种选择器的耗时,这个时间的测量用的是什么方法呢?

  12. yetazhan说道:

    最后再唠叨点什么,

    唠叨的内容本人强烈赞同

  13. r23d说道:

    用的也是这个方法,我抄了qq的图片新闻。至于鼠标事件,使用了事件委托,检测事件触发的对象依据class判断是n还是p.至于上文所说的获取相对于某个节点的位置我想可以使用
    event.clientX是否位于dom.getBoundingClientRect().left和dom.getBoundingClientRect().right之间来判断就行了,应该可行没机会测试,至于说有2像素的bug其实IE中的clientX似乎也多了2像素,都多2像素等于没多。getBoundingClientRect的确是个好东西,就是不知道是不是很耗资源。

  14. 张老师的粉丝说道:

    我挺喜欢你那最后一点唠叨,现在前端确实是这样,你只要不会JQ或没研究过JQ源码,那些傻HR总会拿些破理由把你拒之门外。

  15. EchoFUN说道:

    没大看明白,为啥马云无故躺枪了,难道博主被淘宝给鄙视过~~~?

  16. 一丝说道:

    又是张涵予妹子啊!