1 Contenedor de diseño para el diseño: ocupa el ancho de la ventana gráfica Elementos de la pantalla deslizante (generados dinámicamente, en función del número de imágenes) Nota: 1. querySelector obtiene una lista estática, y debe volver a obtenerse después de agregar elementos dinámicamente 2. A veces el dibujo sigue Sin el dibujo del motor js, la solución: la pantalla deslizante básica del temporizador 2 Obtenga la posición del elemento y el dedo (cuando se hace clic en el contenedor de diseño); obtenga la posición en tiempo real del elemento y calcule el desplazamiento en tiempo real del dedo Sincronice el desplazamiento con el elemento de pantalla deslizante en tiempo real; Versión de posicionamiento de la versión 3 (ajuste el desplazamiento izquierdo del elemento de pantalla deslizante) offsetLeft: el proceso de acumulación -el subíndice de la imagen abstracta- la posición del elemento de pantalla deslizante abstracta 2d versión de transformación ( Capa separada, el costo de redibujar y reordenar desencadenado es menor, la transformación usando translate, translate) translate no se sincronizará con la solución offsetLeft : -Variables , establezca una variable para sincronizar translate, pero esto hará que la lógica de negocios cambie demasiado complejo - definido función css, css una determinada función, los valores especiales establecidas de proceso de varios transforman las transformadas atributos a los nodos usando Li transformada de tipo, y un valor correspondiente a la dos parámetros: operación de lectura 3 parámetros: operación de configuración Atributos del nodo cíclico 4 Pantalla deslizante automática sin costura Sin costura: copie un grupo de imágenes, cuando haga clic en la primera imagen del primer grupo, salte a la primera imagen del segundo grupo instantáneamente cuando haga clic en el primero Cuando la última imagen del segundo grupo, salte a la última imagen del primer grupo Pantalla deslizante automática: función de temporizador de bucle (reiniciar temporizador) borrar temporizador (la lógica del temporizador de bucle no necesita encenderse varias veces, pause la lógica ) Pantalla deslizante automática y conflicto continuo: utilizando la misma variable de índice , el código js en el archivo html es el siguiente: el archivo cl.js introducido es extraer la estructura generada dinámicamente, la pantalla deslizante automática y el código de traducción sincrónica (función css) Archivo Js.
<script type="text/javascript" src="js/cl.js"></script>
<script type="text/javascript">
window.onload = function () {
document.addEventListener('touchstart',function (ev) {
ev = ev || event
ev.preventDefault()
})
var arr = ["img/01.jpg","img/02.jpg","img/03.jpg","img/04.jpg","img/05.jpg"]
cl.carousel(arr)
}
</script>
código de archivo cl.js:
!(function (w) {
// 将函数绑给window的cl属性上
w.cl = {};
w.cl.css = function(node,type,val) {
// 判断节点transform对象是否存在,不存在则添加
if (typeof node === "object" && typeof node["transform"] == "undefined") {
node["transform"] = {};
}
if(arguments.length >= 3){// 写操作
//设置
var text = "";
// 加入两次传入同样属性的变换,则会被覆盖
// 只会更改改变的值,之前没有改变的值则不会改变
node["transform"][type] = val;
// in操作符,会查找对象实例本身及原型链上所有的属性,可能会对后续操作产生影响
for (item in node["transform"]) {
if(node["transform"].hasOwnProperty(item)){
switch (item){
case "translateX":
case "translateY":
text += item + "(" + node["transform"][item] + "px)";
break;
case "scale":
text += item + "(" + node["transform"][item] + ")";
break;
case "roate":
text += item + "(" + node["transform"][item] + "deg)";
break;
}
}
}
// 兼容性问题
node.style.transform = node.style.webkitTransform = text;
}else if(arguments.length == 2){
// 读操作
// 此时只传入了2个参数,第3个参数并没有用上,所以可以利用未使用的第3个参数返回结果
val = node["transform"][type];
if (typeof val === 'undefined'){
switch (type){
case "translateX":
case "translateY":
case "rotate":
val = 0;
break;
case "scale":
val = 1;
break;
}
}
return val;
}
}
w.cl.carousel = function (arr) {
// 布局
var carouselWrap = document.querySelector(".carousel-wrap");
if(carouselWrap){
var pointsLength = arr.length;
// 无缝
var needCarousel = carouselWrap.getAttribute('needCarousel');
needCarousel = needCarousel == null? false:true;
//console.log(needCarousel);
if(needCarousel){
arr = arr.concat(arr);
}
var ulNode = document.createElement('ul');
var styleNode = document.createElement('style')
ulNode.classList.add('list');
for(var i=0;i<arr.length;i++){
ulNode.innerHTML += "<li><a href='javascript:;'><img src="+ arr[i] + " alt='picture'></a></li>"
}
styleNode.innerHTML = ".carousel-wrap > .list{width:"+ (arr.length*100) +"%;}.carousel-wrap > .list > li{width:"+ (1/arr.length*100) +"%;}"
carouselWrap.appendChild(ulNode);
document.head.appendChild(styleNode);
var imgNode = document.querySelector('.carousel-wrap > .list > li > a > img')
// 如果不设置定时器,可能获取到img时,还没有渲染完,此时无法获取其高度
setTimeout(function () {
carouselWrap.style.height = imgNode.offsetHeight + 'px';
},100)
var pointsWrap = document.querySelector('.carousel-wrap > .points-wrap');
if(pointsWrap) {
for (var i = 0; i < pointsLength; i++) {
if(i == 0){
pointsWrap.innerHTML += "<span class='active'></span>";
} else {
pointsWrap.innerHTML += "<span></span>";
}
}
var pointsSpan = document.querySelectorAll('.carousel-wrap > .points-wrap > span');
}
// 滑屏
/*
* 1 拿到元素一开始的位置
* 2 拿到手指一开始点击的位置
* 3 拿到手指move的实时距离
* 4 将手指移动的距离加给元素
*/
var index = 0;
// 手指的位置
var startX = 0;
// 元素的位置
var elementX = 0;
// 保存实时偏移量
//var translateX = 0;
carouselWrap.addEventListener('touchstart',function (ev) {
ev = ev || event;
// changedTouches是列表,取一个就够了
var touchC = ev.changedTouches[0];
ulNode.style.transition = 'none';
// 无缝逻辑,点击第一组的第一张是瞬间跳到第二组的第一张
//点击第二组的最后一张时,瞬间跳到第一组的最后一张
// index代表ul的位置
// 无缝
if(needCarousel){
var index = cl.css(ulNode,"translateX")/document.documentElement.clientWidth;
if(-index === 0){
index = -pointsLength;
} else if (-index === arr.length-1) {
index = -pointsLength + 1;
}
cl.css(ulNode,"translateX",index*document.documentElement.clientWidth);
}
startX = touchC.clientX;
//elementX = ulNode.offsetLeft;
//elementX = translateX;
elementX = cl.css(ulNode,"translateX")
// 停止自动轮播
clearInterval(timer)
})
carouselWrap.addEventListener('touchmove',function (ev) {
ev = ev || event;
var touchC = ev.changedTouches[0]
// 获取滑动时手指的位置
var nowX = touchC.clientX;
// 手指移动的距离
var disX = nowX - startX;
//translateX = elementX + disX
//ulNode.style.left = elementX + disX + 'px';
cl.css(ulNode,"translateX",elementX+disX);
})
carouselWrap.addEventListener('touchend',function (ev) {
ev = ev || event;
//var index = ulNode.offsetLeft/document.documentElement.clientWidth;
//var index = translateX/document.documentElement.clientWidth;
index = cl.css(ulNode,"translateX")/document.documentElement.clientWidth;
index = Math.round(index)
if(index > 0){
index = 0
} else if (index < -arr.length+1) {
index = -arr.length+1
}
syncPoints(index)
ulNode.style.transition = '.5s left';
//ulNode.style.left = index * (document.documentElement.clientWidth) + 'px'
// translate造成的元素偏移并不会同步到offsetLeft上,因为两者不在同个一个图层
//translateX = index * (document.documentElement.clientWidth)
//ulNode.style.transform = "translateX("+ translateX + "px)" ;
cl.css(ulNode,"translateX",index * (document.documentElement.clientWidth));
// 开启自动轮播
if(needAuto){
auto();
}
})
// 自动轮播
var timer = 0;
var needAuto = carouselWrap.getAttribute('needAuto')
needAuto = needAuto == null ? false:true;
//console.log(needAuto);
if(needAuto){
auto();
}
function auto() {
clearInterval(timer)
timer = setInterval(function () {
if(index === -arr.length+1){
ulNode.style.transition = "none";
index = -arr.length/2+1;
cl.css(ulNode,"translateX",index*document.documentElement.clientWidth)
}
setTimeout(function () {
index--;
ulNode.style.transition = "1s transform"
syncPoints(index)
cl.css(ulNode,"translateX",index*document.documentElement.clientWidth)
},50)
},2000)
}
// 同步小圆点的函数
function syncPoints(index) {
if(!pointsWrap){
return;
}
// 同步小圆点
for (var i = 0; i < pointsSpan.length; i++) {
pointsSpan[i].classList.remove('active');
}
pointsSpan[-index%pointsLength].classList.add('active');
}
}
}
})(window)