目录
[代码]php代码:
首页 web前端 js教程 JS实现无限划动的图片全屏浏览

JS实现无限划动的图片全屏浏览

May 27, 2017 am 10:46 AM
js

  无限加载策略

  既然是无限划动,就不能获取所有图片同时加载; 因为要有划动效果,因此当前图片的左右两张需要预加载。 所以可以用三张图片作为一个窗口,使用轮换策略来实现一个无限划动的列表。

<p class="lightbox">
  <p class="container">
    <p class="lightbox-item prev"></p>
    <p class="lightbox-item current"></p>
    <p class="lightbox-item next"></p>
  </p>
</p> 
登录后复制

  其中.lightbox全屏布局, 其中的.lightbox-item包含了上一张、当前、下一张图片。 每当图片划动时我们把下一张变成上一张,当前图变成上一张, 把原来的上一张作为下一张并预先载入下一张图片资源。

  注意这里添加了额外的一层.container并让它包装所有图片。 这样当我们需要图片进行整体滑动时,就可以给它做一个动画。

  布局样式

  我们将.lightbox设为全屏,.prev放到当前屏幕的左边,而.next放到右边。

.lightbox, .container .lightbox-item{
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    background-color: #000;
}
.container{
    position: absolute;
}
.lightbox-item{
    /* 我们用背景图来显示图片 */
    position: absolute;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}
.lightbox-item.prev{
    left: -100%;
    right: 100%;
}
.lightbox-item.next{
    left: 100%;
    right: -100%;
}
登录后复制

  在某些浏览器下(例如某款三星的自带浏览器),它会发现页面内容其实有页面的三倍宽。 于是就把页面变宽使得三张图都显示出来。设置overflow可修复该问题:

.lightbox{
    overflow: hidden;
}
登录后复制

  绑定触摸事件

  图片划动效果的关键在于用户的触摸事件,因为是全屏浏览所以可以直接绑定到window上。 但绑定到window上我们便要注意冲突和解绑的问题,可以.off你注册的函数, 也可以添加一个命名空间,例如:

$(window)
    .on(&#39;mouseup.lightbox touchend.lightbox&#39;, onTouchEnd)
    .on(&#39;mousemove.lightbox touchmove.lightbox&#39;, onTouchMove)
    .on(&#39;mousedown.lightbox touchstart.lightbox&#39;, onTouchBegin)
$(window)
    .off(&#39;mouseup.lightbox touchend.lightbox&#39;)
    .off(&#39;mousemove.lightbox touchmove.lightbox&#39;)
    .off(&#39;mousedown.lightbox touchstart.lightbox&#39;)
登录后复制

  这里面有6个重点的事件,分别是:

  •   mousedown, mousemove, mouseup: 鼠标按下,移动和放松;

  •   touchbegin, touchmove, touchend: 触摸按下,移动和离开。

  图片滑动动画

  其实图片随着手指移动并非动画,只需在touchmove时更新其位置即可。 

// 起始位置,划动距离
var beginX, translateX;
function onTouchBegin(e){
    beginX = getCursorX(e);
}
function getCursorX(e) {
    // 如果是鼠标事件
    if ([&#39;mousemove&#39;, &#39;mousedown&#39;].indexOf(e.type) > -1) {
        return e.pageX;
    }
    // 如果是触摸事件
    return e.changedTouches[0].pageX;
}
function onTouchMove(e){
    translateX = getCursorX(e) - beginX;
    $(&#39;.container&#39;)
        .attr(&#39;transform:translate3d(&#39; + translateX + &#39;)&#39;);
        .attr(&#39;-webkit-transform:translate3d(&#39; + translateX + &#39;)&#39;);
}
登录后复制

  这里的-webkit-transform是为了兼容Android UC浏览器,其他貌似都OK。 另外需要注意translate3d会启用硬件加速,而translateX则没有。 因此translateX在普通的Android浏览器性能都很差。

  当遇到兼容性问题时,真想说天煞的UC。但转念一想至少不用兼容IE6,也不必抱怨太多了。

  判断滑动目标

  上述代码还差一个onTouchEnd,即用户划动了一段距离后松手将会发生什么? 如果划动距离已经足够大,那么就继续动画滑动到下一张,否则就恢复原来的位置。 同时也需要检测划动速度,如果距离很短但速度非常大,也应当进行图片切换。

  我们平时划动图片时是否从未考虑过这里的细节?

  在onTouchBegin中记录开始时间,在onTouchEnd中即可计算速度。

var beginTime, endTime;
function onTouchBegin(e){
    beginTime = Date.now();
}
function onTouchEnd(e){
    endTime = Date.now();
    animateTo(getTarget());
}
登录后复制

  这里getTarget()用来计算划动到的图片,而animateTo则调用一个划动动画。 

[代码]php代码:

function getTarget(){
    // 首先检测划动距离,返回 -1, 0, 1 表示上一张,当前,下一张
    var direction = getDirection(translateX, 0.3 * $(window).width());
    // 如果划动距离检测为0,继续检测速度
    if (direction === 0) {
        var deltaT = Math.max(endTime - beginTime, 1);
        var v = translateX / deltaT;
        direction = getDirection(v, 0.3);
    }
    return [&#39;.prev&#39;, &#39;.current&#39;, &#39;.next&#39;][direction + 1];
}
function getDirection(offset, max) {
    if (offset > max) return -1;
    if (offset < -max) return 1;
    return 0;
}
登录后复制

  划动结束后的动画

  划动结束后,我们需要将.container滑动到目标图片。 为了避免生硬地将当前图片替换为目标图片,我们设置transform动画到目标位置,再悄然替换。 下面便是animateTo的主要逻辑:

// 计算划动到的目标图片对应的translateX
var translateX = $(window).width() * (1 - idx);
$(&#39;.container&#39;).animate({
    &#39;transform&#39;: &#39;translate3d(&#39; + translateX + &#39;px, 0px, 0px)&#39;
    &#39;-webkit-transform&#39;: &#39;translate3d(&#39; + translateX + &#39;px, 0px, 0px)&#39;
}, {
    duration: 1000,
    complete: function() {
        // 动画结束后进行图片轮换
        var $wps = $(&#39;.container&#39;).find(&#39;.lightbox-item&#39;);
        var $prev = $wps.filter(&#39;.prev&#39;);
        var $curr = $wps.filter(&#39;.current&#39;);
        var $next = $wps.filter(&#39;.next&#39;);
        if (target === &#39;.prev&#39;) {
            idx--;
            $prev.attr(&#39;class&#39;, &#39;lightbox-item current&#39;);
            $curr.attr(&#39;class&#39;, &#39;lightbox-item next&#39;);
            $next.attr(&#39;class&#39;, &#39;lightbox-item prev&#39;);
            prefetch(&#39;.prev&#39;, idx - 1);
        } else if (target === &#39;.next&#39;) {
            idx++;
            $next.attr(&#39;class&#39;, &#39;lightbox-item current&#39;);
            $curr.attr(&#39;class&#39;, &#39;lightbox-item prev&#39;);
            $prev.attr(&#39;class&#39;, &#39;lightbox-item next&#39;);
            prefetch(&#39;.next&#39;, idx + 1);
        }
        $(.container).css(&#39;transform&#39;, &#39;none&#39;);
        $(.container).css(&#39;-webkit-transform&#39;, &#39;none&#39;);
    }
});
登录后复制

  还记得吗?我们在图片滑动后需要去预取下一张。如此图片才能连续地进行划动。 prefetch的操作便是从服务器预取下一张图片地址,然后替换掉滑动窗口中最旧的那张图。 其具体实现也和服务器有关,这里不再赘述了。

  注意!当动画结束时对.prev,.current,.next进行轮换并重置transform。 如果重置为translate3d(0,0,0)则动画仍会继续,页面就会跳一下。 如果重置为none则会非常平滑,同时别忘了-webkit-transform来兼容更多浏览器。

  TouchBegin 的兼容性

  在Android ICS下如果touchbegin和第一个touchmove中都未调用 preventDefault, 后续的touchmove和touchend就不会被触发。 解决办法当然是在onTouchBegin中进行preventDefault(), 然而这样click事件(点击关闭全屏啊!)就不会被触发了:

function onTouchBegin(e) {
    e.preventDefault();
}
登录后复制

  所以我们需要在onTouchMove中来判断这是否是一个Click,并手动触发它的行为。

function onTouchMove(e){
    if(isClick()) onClick(); 

    function isClick() {
        var deltaT = endTime - beginTime;
        var deltaX = Math.abs(translateX);
        // 时间很短,并且移动距离很小,那么应该是个点击!
        return deltaT < 700 && deltaX < 7;
    }
}
登录后复制

  图片渐进载入

  当网速很慢时,连续划动就可能使得旧的图片显示出来(因为预取请求仍未返回)。 常见的一个实践是:立即使用一个已经载入的图片来作为Placeholder, 当目标图片载入后用它替换掉当前的Placeholder。

function loadImage($img, src){
    // 先设置一个Placeholder
    $img.attr(&#39;src&#39;, 
        &#39;data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==&#39;);
    // 载入图片到临时变量
    var tmp = new Image();
    tmp.onload = function(){
        // 资源载入后,将资源显示到目标的img
        $img.src = src;
    };
    tmp.src = src;
}
登录后复制

  设置背景图与设置src属性一样,均可以使用该策略。浏览器会复用那个资源。

  图片到底提示

  在第一张图片右划和最后一张图片左划时,应当给出提示。 可以做一张带有提示信息的Placeholder:

$lightbox.attr(&#39;style&#39;, &#39;top:0;left:0;right:0;bottom:0;&#39;);
$lightbox.append($(&#39;<p class="alert-nomore">&#39;).html(&#39;没有更多了..&#39;));
登录后复制

  然后让文字居中:

.lightbox-item .alert-nomore{
    position: absolute;
    text-align: center;
    bottom: 50%;
    left: 0;
    right: 0;
    color: #777;
    font-size: 20px;
}
登录后复制

以上是JS实现无限划动的图片全屏浏览的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用JS和百度地图实现地图平移功能 如何使用JS和百度地图实现地图平移功能 Nov 21, 2023 am 10:00 AM

如何使用JS和百度地图实现地图平移功能百度地图是一款广泛使用的地图服务平台,在Web开发中经常用于展示地理信息、定位等功能。本文将介绍如何使用JS和百度地图API实现地图平移功能,并提供具体的代码示例。一、准备工作使用百度地图API前,首先需要在百度地图开放平台(http://lbsyun.baidu.com/)上申请一个开发者账号,并创建一个应用。创建完成

推荐:优秀JS开源人脸检测识别项目 推荐:优秀JS开源人脸检测识别项目 Apr 03, 2024 am 11:55 AM

人脸检测识别技术已经是一个比较成熟且应用广泛的技术。而目前最为广泛的互联网应用语言非JS莫属,在Web前端实现人脸检测识别相比后端的人脸识别有优势也有弱势。优势包括减少网络交互、实时识别,大大缩短了用户等待时间,提高了用户体验;弱势是:受到模型大小限制,其中准确率也有限。如何在web端使用js实现人脸检测呢?为了实现Web端人脸识别,需要熟悉相关的编程语言和技术,如JavaScript、HTML、CSS、WebRTC等。同时还需要掌握相关的计算机视觉和人工智能技术。值得注意的是,由于Web端的计

如何使用PHP和JS创建股票蜡烛图 如何使用PHP和JS创建股票蜡烛图 Dec 17, 2023 am 08:08 AM

如何使用PHP和JS创建股票蜡烛图股票蜡烛图是股票市场中常见的一种技术分析图形,通过绘制股票的开盘价、收盘价、最高价和最低价等数据,帮助投资者更直观地了解股票的价格波动情况。本文将教你如何使用PHP和JS创建股票蜡烛图,并附上具体的代码示例。一、准备工作在开始之前,我们需要准备以下环境:1.一台运行PHP的服务器2.一个支持HTML5和Canvas的浏览器3

股票分析必备工具:学习PHP和JS绘制蜡烛图的步骤 股票分析必备工具:学习PHP和JS绘制蜡烛图的步骤 Dec 17, 2023 pm 06:55 PM

股票分析必备工具:学习PHP和JS绘制蜡烛图的步骤,需要具体代码示例随着互联网和科技的快速发展,股票交易已经成为许多投资者的重要途径之一。而股票分析是投资者决策的重要一环,其中蜡烛图被广泛应用于技术分析中。学习如何使用PHP和JS绘制蜡烛图将为投资者提供更多直观的信息,帮助他们更好地做出决策。蜡烛图是一种以蜡烛形状来展示股票价格的技术图表。它展示了股票价格的

如何使用JS和百度地图实现地图点击事件处理功能 如何使用JS和百度地图实现地图点击事件处理功能 Nov 21, 2023 am 11:11 AM

如何使用JS和百度地图实现地图点击事件处理功能概述:在Web开发中,经常需要使用地图功能来展示地理位置和地理信息。而地图上的点击事件处理是地图功能中常用且重要的一部分。本文将介绍如何使用JS和百度地图API来实现地图的点击事件处理功能,并给出具体的代码示例。步骤:导入百度地图的API文件首先,要在HTML文件中导入百度地图API的文件,可以通过以下代码实现:

如何使用JS和百度地图实现地图热力图功能 如何使用JS和百度地图实现地图热力图功能 Nov 21, 2023 am 09:33 AM

如何使用JS和百度地图实现地图热力图功能简介:随着互联网和移动设备的迅速发展,地图成为了一种普遍的应用场景。而热力图作为一种可视化的展示方式,能够帮助我们更直观地了解数据的分布情况。本文将介绍如何使用JS和百度地图API来实现地图热力图的功能,并提供具体的代码示例。准备工作:在开始之前,你需要准备以下事项:一个百度开发者账号,并创建一个应用,获取到相应的AP

PHP与JS开发技巧:掌握绘制股票蜡烛图的方法 PHP与JS开发技巧:掌握绘制股票蜡烛图的方法 Dec 18, 2023 pm 03:39 PM

随着互联网金融的迅速发展,股票投资已经成为了越来越多人的选择。而在股票交易中,蜡烛图是一种常用的技术分析方法,它能够显示股票价格的变化趋势,帮助投资者做出更加精准的决策。本文将通过介绍PHP和JS的开发技巧,带领读者了解如何绘制股票蜡烛图,并提供具体的代码示例。一、了解股票蜡烛图在介绍如何绘制股票蜡烛图之前,我们首先需要了解一下什么是蜡烛图。蜡烛图是由日本人

js和vue的关系 js和vue的关系 Mar 11, 2024 pm 05:21 PM

js和vue的关系:1、JS作为Web开发基石;2、Vue.js作为前端框架的崛起;3、JS与Vue的互补关系;4、JS与Vue的实践应用。

See all articles