js 轮播图源码_js轮播图代码

源码大全 编辑:速达网络 日期:2024-03-30 15:29:53 3人浏览

轮播图已成为网站、移动应用等交互界面中不可或缺的元素。轮播图能够高效地展示多张图片或内容,提升用户体验。JavaScript(JS)作为前端开发的核心技术之一,在轮播图的实现中发挥着重要作用。本文将深入解析JS轮播图源码,分析其工作原理,并提出优化策略,以期为前端开发者提供有益的参考。

一、JS轮播图源码解析

1. HTML结构

轮播图的HTML结构通常包含以下元素:

(1)轮播容器:用于承载轮播图片的容器。

(2)轮播按钮:用于切换轮播图片的按钮。

(3)轮播指示器:用于显示当前轮播图片位置的指示器。

以下是一个简单的HTML结构示例:

```html

详解如何使用原生JS实现移动端web轮播图效果

在做移动端开发的时候,必不可少的是轮播图,下面这篇文章主要给大家介绍了关于利用纯JS实现移动端web轮播图的相关资料,重要的是结合Tween算法造轮子,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。

前言

相信大家应该都知道,移动端的轮播图是我们比较常见的需求, 我们最快的实现方式往往是 使用第三方的代码, 例如 swiper , 但当遇到一些比较复杂的轮播图需求时, 往往是束手无策,不知道怎么改.

所以我们要尝试去自己造一些轮子, 以适应各种复杂多变的需求; 另外一点, 自己写的代码如果有bug是很容易修复的, 对自身的提高也很大.

在没有阅读swiper源码的过程下,我尝试自己实现一个简易而不失实用的移动端轮播图, 经过几个小时的思考和实践终于还是实现了(如图):

实现移动端的轮播图要比pc复杂一些,主要表现在以下几个方面:

1.轮播图要适应不同宽度/dpr的屏幕

2.需要使用 touch相关的事件

3.不同机型对 touch事件支持的不太一样,可能会有一些兼容性问题

4.手指移动图片一部分距离,剩下的距离需要自动完成

5.自动完成距离需要有 ease 时间曲线

但编程解决问题的思路都是差不多的,

我们在使用轮播图的时候可以仔细观察,通过现象看到本质:

我们在使用轮播图的时候可以仔细观察,通过现象看到本质:

手指放在图片上, 手指向左或者向右移动, 图片也随之移动;

手指移动的距离少时,图片自动复原位置;手指移动的距离多时,自动切换到下一张;

手指向左或者向右移动的快时,会切换到下一张;

图片轮播是无限循环的, 我们需要采用 3 1 2 3 1的方式来实现, 即 N+2张图来实现N张图的无限循环轮播

我们通过分析现象,可以提出一个基本实现方案:

1. 手指触摸事件可以通过 touchstart touchmove touchend 3个事件来实现

2.在手指 touchstart的时候我们需要记录 手指的x坐标, 可以使用 touch的pageX属性; 还有 这个时间点,

3.手指touchmove的时候我们也需要记录pageX,并且记录累计移动的距离 moveX

4.手指离开的时候,记录时间点, 根据前两步计算的 x方向移动的距离,时间点之差

5.通过比较x方向移动距离来判断移动方向, 以及是否应该切换到下一张图; 根据时间判断用户是否进行了左右扫动的操作

6.移动图片可以使用 translate3d来实现,开启硬件加速

7.移动一段距离需要 easeOut效果,我们可以使用 Tween算法中的easeOut来实现我们每次移动的距离; 当然也可以使用 js设置 transition动画

实现源码(仅供参考):

head头部样式

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width,initial-scale=.5,maximum-scale=.5">

<title>移动端轮播图</title>

<style>

* {

box-sizing: border-box;

margin: 0;

padding: 0

}

.banner {

overflow: hidden;

width: 100%;

height: 300px

}

.banner .img-wrap {

position: relative;

height: 100%

}

.banner img {

display: block;

position: absolute;

top: 0;

width: 100%;

height: 100%

}

</style>

</head>HTML结构

<p class="banner">

<p class="img-wrap" id="imgWrap">

<img src="images/banner_3.jpg" data-index="-1">

<img src="images/banner_1.jpg" data-index="0">

<img src="images/banner_2.jpg" data-index="1">

<img src="images/banner_3.jpg" data-index="2">

<img src="images/banner_1.jpg" data-index="3">

</p>

</p>JS代码1, easeOut动画式移动,

这里的 HTMLElement.prototype.tweenTranslateXAnimate ,是给所有的HTML元素类扩展的tweenTranslateXAnimate方法

移动一段距离我们需要使用定时器来帮助我们完成,这个重复的操作

<script>

HTMLElement.prototype.tweenTranslateXAnimate = function (start, end, callback) {

var duration = 50;

var t = 0;

var vv = end - start;

var Tween = {

Quad: {

easeOut: function (t, b, c, d) {

return -c * (t /= d) * (t - 2) + b;

}

}

};

this.timer = setInterval(function () {

var dis = start + Tween.Quad.easeOut(++t, 0, vv, duration);

this.style.transform = 'translate3d(' + dis + 'px, 0, 0)';

if (vv > 0 && parseInt(this.style.transform.slice(12)) >= end) {

this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)';

clearInterval(this.timer);

callback && callback();

}

if (vv < 0 && parseInt(this.style.transform.slice(12)) <= end) {

this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)';

clearInterval(this.timer);

callback && callback();

}

}.bind(this), 4);

}

</script>touch事件部分

<script>

~function () {

var lastPX = 0; // 上一次触摸的位置x坐标, 需要计算出手指每次移动的一点点距离

var movex = 0; // 记录手指move的x方向值

var imgWrap = document.getElementById('imgWrap');

var startX = 0; // 开始触摸时手指所在x坐标

var endX = 0; // 触摸结束时手指所在的x坐标位置

var imgSize = imgWrap.children.length - 2; // 图片个数

var t1 = 0; // 记录开始触摸的时刻

var t2 = 0; // 记录结束触摸的时刻

var width = window.innerWidth; // 当前窗口宽度

var nodeList = document.querySelectorAll('#imgWrap img'); // 所有轮播图节点数组 NodeList

// 给图片设置合适的left值, 注意 querySelectorAll返回 NodeList, 具有 forEach方法

nodeList.forEach(function (node, index) {

node.style.left = (index - 1) * width + 'px';

});

/**

* 移动图片到当前的 tIndex索引所在位置

* @param {number} tIndex 要显示的图片的索引

* */

function toIndex(tIndex) {

var dis = -(tIndex * width);

var start = parseInt(imgWrap.style.transform.slice(12));

// 动画移动

imgWrap.tweenTranslateXAnimate(start, dis, function () {

setTimeout(function () {

movex = dis;

if (tIndex === imgSize) {

imgWrap.style.transform = 'translate3d(0, 0, 0)';

movex = 0;

}

if (tIndex === -1) {

imgWrap.style.transform = 'translate3d(' + width * (1 - imgSize) + 'px, 0, 0)';

movex = -width * (imgSize - 1);

}

}, 0);

});

}

/**

* 处理各种触摸事件 ,包括 touchstart, touchend, touchmove, touchcancel

* @param {Event} evt 回调函数中系统传回的 js 事件对象

* */

function touch(evt) {

var touch = evt.targetTouches[0];

var tar = evt.target;

var index = parseInt(tar.getAttribute('data-index'));

if (evt.type === 'touchmove') {

var di = parseInt(touch.pageX - lastPX);

endX = touch.pageX;

movex += di;

imgWrap.style.webkitTransform = 'translate3d(' + movex + 'px, 0, 0)';

lastPX = touch.pageX;

}

if (evt.type === 'touchend') {

var minus = endX - startX;

t2 = new Date().getTime() - t1;

if (Math.abs(minus) > 0) { // 有拖动操作

if (Math.abs(minus) < width * 0.4 && t2 > 500) { // 拖动距离不够,返回!

toIndex(index);

} else { // 超过一半,看方向

console.log(minus);

if (Math.abs(minus) < 20) {

console.log('距离很短' + minus);

toIndex(index);

return;

}

if (minus < 0) { // endX < startX,向左滑动,是下一张

toIndex(index + 1)

} else { // endX > startX ,向右滑动, 是上一张

toIndex(index - 1)

}

}

} else { //没有拖动操作

}

}

if (evt.type === 'touchstart') {

lastPX = touch.pageX;

startX = lastPX;

endX = startX;

t1 = new Date().getTime();

}

return false;

}

imgWrap.addEventListener('touchstart', touch, false);

imgWrap.addEventListener('touchmove', touch, false);

imgWrap.addEventListener('touchend', touch, false);

imgWrap.addEventListener('touchcancel', touch, false);

}();

</script>在触摸事件中最关键的参数是 pageX参数, 记录x的位置.

当然这只是一个demo,还需要进一步的优化和封装, 以便于我们用在真实的项目.

本demo仅仅是提供了一个解决问题的思路, 有了这个思路,相信各种复杂的需求也得以解决...

js原生代码实现轮播图

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>最简单的轮播广告</title>

<style>

body, div, ul, li {

margin: 0;

padding: 0;

}

ul {

list-style-type: none;

}

body {

background: #000;

text-align: center;

font: 12px/20px Arial;

}

#box {

position: relative;

width: 492px;

height: 172px;

background: #fff;

border-radius: 5px;

border: 8px solid #fff;

margin: 10px auto;

}

#box .list {

position: relative;

width: 490px;

height: 170px;

overflow: hidden;

border: 1px solid #ccc;

}

#box .list li {

position: absolute;

top: 0;

left: 0;

width: 490px;

height: 170px;

opacity: 0;

transition: opacity 0.5s linear

}

#box .list li.current {

opacity: 1;

}

#box .count {

position: absolute;

right: 0;

bottom: 5px;

}

#box .count li {

color: #fff;

float: left;

width: 20px;

height: 20px;

cursor: pointer;

margin-right: 5px;

overflow: hidden;

background: #F90;

opacity: 0.7;

border-radius: 20px;

}

#box .count li.current {

color: #fff;

opacity: 0.7;

font-weight: 700;

js 轮播图源码_js轮播图代码

background: #f60

}

</style>

</head>

<body>

<div id="box">

<ul class="list">

<li class="current" style="opacity: 1;"><img src="img/images04/01.jpg" width="490" height="170"></li>

<li style="opacity: 0;"><img src="img/images04/02.jpg" width="490" height="170"></li>

<li style="opacity: 0;"><img src="img/images04/03.jpg" width="490" height="170"></li>

<li style="opacity: 0;"><img src="img/images04/04.jpg" width="490" height="170"></li>

<li style="opacity: 0;"><img src="img/images04/05.jpg" width="490" height="170"></li>

</ul>

<ul class="count">

<li class="current">1</li>

<li class="">2</li>

<li class="">3</li>

<li class="">4</li>

<li class="">5</li>

</ul>

</div>

<script>

var box=document.getElementById('box');

var uls=document.getElement**yTagName('ul');

var imgs=uls[0].getElement**yTagName('li');

var btn=uls[1].getElement**yTagName('li');

var i=index=0; //中间量,统一声明;

var play=null;

console.log(box,uls,imgs,btn);//获取正确

//图片切换, 淡入淡出效果我是用(transition: opacity 0.8s linear)做的,不纠结、简单 在css里面

function show(a){ //方法定义的是当传入一个下标时,按钮和图片做出对的反应

for(i=0;i<btn.length;i++ ){

btn[i].className=''; //很容易看懂吧?每个按钮都先设置成看不见,然后把当前按钮设置成可见。

btn[a].className='current';

}

for(i=0;i<imgs.length;i++){ //把图片的效果设置和按钮相同

imgs[i].style.opacity=0;

imgs[a].style.opacity=1;

}

}

//切换按钮功能,响应对应图片

for(i=0;i<btn.length;i++){

btn[i].index=i; //不知道你有没有发现,循环里的方法去调用循环里的变量体i,会出现调到的不是i的变动值的问题。所以我先在循环外保存住

btn[i].onmouseover=function(){

show(this.index);

clearInterval(play); //这就是最后那句话追加的功能

}

}

//自动轮播方法

function autoPlay(){

play=setInterval(function(){ //这个paly是为了保存定时器的,变量必须在全局声明 不然其他方法调不到 或者你可以调用auto.play 也许可以但是没时间试了

index++;

index>=imgs.length&&(index=0);//可能有优先级问题,所以用了括号,没时间测试了。

show(index);

},1000)

}

autoPlay();//马上调用,我试过用window.onload调用这个方法,但是调用之后影响到了其他方法,使用autoPlay所以只能这样调用了

//div的鼠标移入移出事件

box.onmouseover=function(){

clearInterval(play);

};

box.onmouseout=function(){

autoPlay();

};

//按钮下标也要加上相同的鼠标事件,不然图片停止了,定时器没停,会突然闪到很大的数字上。 貌似我可以直接追加到之前定义事件中。

</script>

</body>

</html>

js代码实现banner图片轮播

这是我以前写过的一个,样式你改一下就OK了

<div class="fbanner widget3924">

<div id="i_focus">

<div id="i_focus_pic">

<ul id="i_focus_piclist">

<li style="display: none;">

<a href="" target="_blank" style="background: url(/templates/runlinjinguan/images/banner1.jpg) center 0 no-repeat;">

</a>

</li>

<li style="display: list-item;">

<a href="" target="_blank" style="background: url(/templates/runlinjinguan/images/banner4.jpg) center 0 no-repeat;">

</a>

</li>

<li style="display: none;">

<a href="" target="_blank" style="background: url(/templates/runlinjinguan/images/banner3.jpg) center 0 no-repeat;">

</a>

</li>

<li style="display: none;">

<a href="" target="_blank" style="background: url(/templates/runlinjinguan/images/banner2.jpg) center 0 no-repeat;">

</a>

</li>

</ul>

<div id="i_focus_opdiv">

</div>

<ul id="i_focus_btn">

<li id="p0" class="">

<span>

</span>

</li>

<li id="p0" class="i_cur">

<span>

</span>

</li>

<li id="p0" class="">

<span>

</span>

</li>

<li id="p0" class="">

<span>

</span>

</li>

</ul>

</div>

</div>

<script type="text/javascript" src="/templates/runlinjinguan/js/flash.js"></script>

<script type="text/javascript">

$("#i_focus_btn").find("li").eq(0).addClass("i_cur");

</script>

</div>

引用的js文件

// JavaScript Document

//flash js

$(document).ready(function () {

var i_curIndex = 0;

var beauBeauSlide; //函数对象

var i_curID = 0; //取得鼠标下方的对象ID

var pictureID = 0; //索引ID

$("#i_focus_piclist li").eq(0).show(); //默认

autoScroll();

$("#i_focus_btn li").hover(function (e) {

StopScrolll();

$("#i_focus_btn li").removeClass("i_cur") //所有的li去掉当前的样式加上正常的样式

$(this).addClass("i_cur"); //而本身则加上当前的样式去掉正常的样式

i_curID = $(this).attr("id"); //取当前元素的ID

pictureID = $("#i_focus_btn li").index(this);// i_curID.substring(i_curID.length - 1); //取最后一个字符

$("#i_focus_piclist li").eq(pictureID).fadeIn("slow"); //本身显示

$("#i_focus_piclist li").not($("#i_focus_piclist li")[pictureID]).hide(); //除了自身别的全部隐藏

$("#i_focus_tx li").hide();

$("#i_focus_tx li").eq(pictureID).show();

},

function () {

//当鼠标离开对象的时候获得当前的对象的ID以便能在启动自动时与其同步

i_curID = $(this).attr("id"); //取当前元素的ID

pictureID = i_curID.substring(i_curID.length - 1); //取最后一个字符

i_curIndex = pictureID;

autoScroll();

});

//自动滚动

function autoScroll() {

var myNubli = $("#i_focus_btn li").size();

if (myNubli > 1) {

$("#i_focus_btn li:last").removeClass("i_cur");

$("#i_focus_tx li:last").hide();

$("#i_focus_btn li").eq(i_curIndex).addClass("i_cur");

$("#i_focus_btn li").eq(i_curIndex - 1).removeClass("i_cur");

$("#i_focus_tx li").eq(i_curIndex).show();

$("#i_focus_tx li").eq(i_curIndex - 1).hide();

$("#i_focus_piclist li").eq(i_curIndex).fadeIn("slow");

$("#i_focus_piclist li").eq(i_curIndex - 1).hide();

i_curIndex++;

i_curIndex = i_curIndex >= myNubli ? 0 : i_curIndex;

beauBeauSlide = setTimeout(autoScroll, 5000);

}

}

function StopScrolll() //当鼠标移动到对象上面的时候停止自动滚动

{

clearTimeout(beauBeauSlide);

}

});

//第二个渐隐幻灯开始

var defaultOpts = {

interval: 3000,

fadeInTime: 800,

fadeOutTime: 500

};

var _titles = $("ul.slide-txt li");

var _titles_bg = $("ul.op li");

var _bodies = $("ul.slide-pic li");

var _count = _titles.length;

var _current = 0;

var _intervalID = null;

var stop = function () {

window.clearInterval(_intervalID);

};

var slide = function (opts) {

if (opts) {

_current = opts.current || 0;

} else {

_current = (_current >= (_count - 1)) ? 0 : (++_current);

};

_bodies.filter(":visible").fadeOut(defaultOpts.fadeOutTime,

function () {

_bodies.eq(_current).fadeIn(defaultOpts.fadeInTime);

_bodies.removeClass("cur").eq(_current).addClass("cur");

});

_titles.removeClass("cur").eq(_current).addClass("cur");

_titles_bg.removeClass("cur").eq(_current).addClass("cur");

}; //endof slide

var go = function () {

stop();

_intervalID = window.setInterval(function () {

slide();

},

defaultOpts.interval);

}; //endof go

var itemMouseOver = function (target, items) {

stop();

var i = $.inArray(target, items);

slide({

current: i

});

}; //endof itemMouseOver

_titles.hover(function () {

if ($(this).attr('class') != 'cur') {

itemMouseOver(this, _titles);

} else {

stop();

}

},

go);

//_titles_bg.hover(function() { itemMouseOver(this, _titles_bg); }, go);

_bodies.hover(stop, go);

go();

var slideX = {

_this: $('.catalog .imgbox'),

_btnLeft: $('.catalog .left'),

_btnRight: $('.catalog .right'),

init: function () {

slideX._btnLeft.click(slideX.slideLeft);

slideX._btnRight.click(slideX.slideRight);

},

slideLeft: function () {

slideX._btnLeft.unbind('click', slideX.slideLeft);

for (i = 0; i < 2; i++) {

slideX._this.find('li:last').prependTo(slideX._this);

}

slideX._this.css('marginLeft', -224);

slideX._this.animate({

'marginLeft': 0

},

500,

function () {

slideX._btnLeft.bind('click', slideX.slideLeft);

});

return false;

},

slideRight: function () {

slideX._btnRight.unbind('click', slideX.slideRight);

slideX._this.animate({

'marginLeft': -224

},

500,

function () {

slideX._this.css('marginLeft', '0');

for (i = 0; i < 2; i++) {

slideX._this.find('li:first').appendTo(slideX._this)

}

slideX._btnRight.bind('click', slideX.slideRight);

});

return false;

}

}

$(document).ready(function () {

slideX.init();

})

$(document).ready(function () {

var newTime = new Date();

var newTime = newTime.getTime();

var $imgTmp = $('#topromotion').find('img:first');

var osrc = $imgTmp.attr('src');

$imgTmp.attr('src', osrc + '?' + newTime);

});

希望对你有帮助!

分享到

文章已关闭评论!