同样打印log,三、编写思路

作者: 编程  发布:2019-11-09

一、要做成什么样

接手一个项目,有一个问题需要修改:轮播图不能手动滑动,手动滑动轮播图只会触发侧滑菜单。

本文实例讲述了原生JS实现的轮播图功能。分享给大家供大家参考,具体如下:

  bs端的轮播控件千千万,有的甚至能作为一个单独的库来开发,所涉及到的功能也是缤纷多彩。相对来说,cs端的轮播用得不多,我这里只是简单的做了个能满足一般需求的轮播,在项目中凑会凑会还是可以的。先给两张图,看看最后的效果:

 

一、效果预览:

9159.com 1

猜测:viewpager控件(轮播图)的触摸事件被SlidingMenu控件(侧滑菜单,非第三方项目,乃是上个开发人员自定义的)拦截了。

9159.com 2

9159.com 3

 

由于只能上传2M以下的图片,这里只截取了自动切换的效果:

  如图,整个结构就是左右箭头、底部小点以及内同三大部分。虽然是简易版本,但是我还是加了几个小功能:是否自动开始轮播、轮播间隔、内容是否居中对齐、代码控制当前页码。整个逻辑也就200多行代码,我就不多做讲解了,感兴趣的可以去拉取开源代码:

基于这个猜测,我自定义一个ViewPager,重写dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent,分别在这三个方法中打印log;

二、编写语言

重写SlidingMenu的dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent,同样打印log。

HTML、CSS、原生JS

 

三、编写思路

重新编译运行,手滑轮播图,log如下:

(一)HTML部分

9159.com 49159.com 5

1、.slide意为滑槽,里面存放所有图片;

06-08 09:52:08.394 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:0
06-08 09:52:08.395 19424-19424/com.parkingmore E/SlidingMenu: onInterceptTouchEvent ev:0
06-08 09:52:08.395 19424-19424/com.parkingmore E/RollViewPager: dispatchTouchEvent ev:0
06-08 09:52:08.395 19424-19424/com.parkingmore E/RollViewPager: onInterceptTouchEvent ev:0
06-08 09:52:08.441 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.441 19424-19424/com.parkingmore E/SlidingMenu: onInterceptTouchEvent ev:2
06-08 09:52:08.442 19424-19424/com.parkingmore E/SlidingMenu: ACTION_MOVE dx:15.473999
06-08 09:52:08.442 19424-19424/com.parkingmore E/RollViewPager: ACTION_MOVE getCurrentItem():1
06-08 09:52:08.442 19424-19424/com.parkingmore E/RollViewPager: dispatchTouchEvent ev:2
06-08 09:52:08.442 19424-19424/com.parkingmore E/RollViewPager: onInterceptTouchEvent ev:2
06-08 09:52:08.459 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.459 19424-19424/com.parkingmore E/SlidingMenu: onInterceptTouchEvent ev:2
06-08 09:52:08.459 19424-19424/com.parkingmore E/RollViewPager: dispatchTouchEvent ev:3
06-08 09:52:08.459 19424-19424/com.parkingmore E/RollViewPager: onInterceptTouchEvent ev:3
06-08 09:52:08.477 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.477 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.495 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.495 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.515 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.515 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.533 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.533 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.551 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.551 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.574 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.574 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.594 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.595 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.611 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.612 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.622 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:2
06-08 09:52:08.622 19424-19424/com.parkingmore E/SlidingMenu: onTouchEvent ev:2
06-08 09:52:08.623 19424-19424/com.parkingmore E/SlidingMenu: dispatchTouchEvent ev:1

2、.prev存放向左的箭头,.next存放向右的箭头;

View Code

3、pointer意为指示器,存放下方的五个切换按钮,每个切换按钮用span来表示;

从log中可以看出,该开始,还能将滑动事件传递给ViewPager,之后,就被SlidingMenu拦截了。这个log证实了这个猜想是正确的。

4、.m-view,意为视窗,即每次看到图片的窗口,它存放以上所有的部件;

 

9159.com,(二)CSS部分

知道了原因就好解决了,我现在要考虑的是:要达到什么样的效果。

1、.m-view设为相对定位,他的后代元素可以以它作为绝对定位的参照;

 

2、.slide.prev.nextpointer全都用绝对定位放到合适位置;

预期效果:可以正常滑动轮播图,当轮播图在第一张时,可以滑到侧滑菜单。

3、.slide的所有图片水平排列,且视窗.m-view的宽度设为只有一张图片那么宽,这样默认情况.slide还是会全部显示;当给.m-view设置overflow:hidden后子元素超出它的部分就会隐藏,就实现了只显示一张图片的效果;

 

(三)JS部分

网上有人分享过类似的问题。我这里也借鉴了一下。

1、切换功能:

 

设置一个切换函数toggle实现左切或者右切一张图,toggle有两个子函数leftToggle和rightToggle分别实现向左、向右切换一张图,将他们分别绑定到.prev.next按钮的clik事件;

先来实现第一个功能:可以正常滑动轮播图。

2、切换功能的淡入动画效果

 

只有1的话切换是立即产生的,没有过渡效果;这里利用定时器和步长将切换功能细化到更小的滑动操作leftStep和rightStep,leftToggle和rightToggle通过多次调用滑动操作来实现一次切换,这样就会产生动画效果;

可以设一个全局变量:public static boolean mRollViewPagerTouching;

3、跳转功能

用来表示是否在触摸轮播图。

对指示器的每个圆形按钮绑定跳转功能,跳转实际上是将.slide进行移动;

 

4、自动播放

在自定义ViewPager中,判断是否在触摸轮播图

只需要设置定时器,每隔一定时间执行切换即可;

9159.com 69159.com 7

四、我的代码

public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_DOWN:
                MyApplication.mRollViewPagerTouching = true;
                break;
            case MotionEvent.ACTION_UP:
                MyApplication.mRollViewPagerTouching = false;
                break;
        }
        return super.dispatchTouchEvent(ev);
    }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>轮播图</title>
  <style>
    .m-view,.m-view .slide img{
      position: relative;/*作为绝对定位的父元素*/
      width: 800px;
      height: 600px;
    }
    .m-view{
      overflow: hidden;/*将超出该div的子元素隐藏*/
    }
    .m-view .slide{
      position: absolute;
      width: 8000px;
      height: 600px;
    }
    .m-view .slide img{
      margin-right: -5px;
    }
    .m-view .prev,.m-view .next{
      position: absolute;
      top: 40%;
      font: 60px/60px Microsoft YaHei;
      color: #00BFFF;
    }
    .m-view .prev{
      left: 10px;
    }
    .m-view .next{
      right: 10px;
    }
    .m-view .pointer{
      position: absolute;
      bottom: 40px;
      left: 33%;
    }
    .m-view .pointer span{
      display: inline-block;/*水平排列*/
      width: 40px;
      height: 40px;
      border-radius: 20px;
      margin-right: 10px;
      background-color: #00FF00;
    }
    .m-view .pointer .on{/*点亮当前图片对应的圆圈*/
      background-color: #1E90FF;
    }
  </style>
</head>
<body>
  <div class="m-view">
    <div class="slide" style="left: -800px">
      <img src="../lunbo/5.jpg" alt="4">
      <img src="../lunbo/1.jpg" alt="0">
      <img src="../lunbo/2.jpg" alt="1">
      <img src="../lunbo/3.jpg" alt="2">
      <img src="../lunbo/4.jpg" alt="3">
      <img src="../lunbo/5.jpg" alt="4">
      <img src="../lunbo/1.jpg" alt="0">
    </div>
    <div class="prev"><</div>
    <div class="next">></div>
    <div class="pointer">





    </div>
  </div>
  <script type="text/javascript">
    var view=document.getElementsByClassName('m-view')[0];
    var slide=document.getElementsByClassName('slide')[0];
    var prev=document.getElementsByClassName('prev')[0];
    var next=document.getElementsByClassName('next')[0];
    var button=document.getElementsByClassName('button');
    var curIndex=0;//当前图片的索引位置
    var toggled=true;//是否正在切换,true表明切换已完成,此时才能切换
    /* Toggle函数实现切换一张图片的功能 */
    function Toggle () {
      var TIMER=50;//滑动一次所用的时间,它是setInterval的第二个参数
      var time=800;//每切换一张图片总共用的时长
      var times=time/TIMER;//每切换一张图片需滑动的次数
      var stepLenth=800/times;//每次滑动的步长
      var leftToggle=function () {
        var t1=times;
        function leftStep(){
          slide.style.left=parseInt(slide.style.left)+stepLenth+"px";
          t1--;
          if (!t1) {
            clearInterval(interval);
            curIndex--;
            if (curIndex<0) {
              slide.style.left=parseInt(slide.style.left)-4000+"px";
              curIndex=4;
            };
            toggled=true;
          };
        };
        if (toggled==true) {
          toggled=false;
          button[curIndex].className="button";
          if (curIndex!=0) {
            button[curIndex-1].className="button on";
          }else{
            button[curIndex+4].className="button on";
          }
          var interval=setInterval(leftStep,TIMER);
        };
      };
      var rightToggle=function () {
        var t2=times;
        function leftStep(){
          slide.style.left=parseInt(slide.style.left)-stepLenth+"px";
          t2--;
          if (!t2) {
            clearInterval(interval);
            curIndex++;
            if (curIndex>4) {
              slide.style.left=parseInt(slide.style.left)+4000+"px";
              curIndex=0;
            };
            toggled=true;
          };
        };
        if (toggled==true) {
          toggled=false;
          button[curIndex].className="button";
          if (curIndex!=4) {
            button[curIndex+1].className="button on";
          }else{
            button[curIndex-4].className="button on";
          };
          var interval=setInterval(leftStep,TIMER);
        };
      }
      this.leftToggle=leftToggle;//输出对外的接口
      this.rightToggle=rightToggle;
    };
    var toggle=new Toggle();
    prev.onclick=function () {
      toggle.leftToggle();
    };
    next.onclick=function () {
      toggle.rightToggle();
    };
    /* 点击圆圈跳转功能 */
    for (var i = 0; i < button.length; i++) {
      button[i].onclick=function () {
        var newIndex=parseInt(this.getAttribute("index"));
        if (newIndex!=curIndex) {
          var distance=-800*(newIndex-curIndex);
          slide.style.left=parseInt(slide.style.left)+distance+"px";
          button[curIndex].className="button";
          button[newIndex].className="button on";
          curIndex=newIndex;
        };
      };
    }
    /* 自动播放功能,鼠标移上去停止播放,移开再次播放 */
    var intervalo=setInterval(toggle.rightToggle,3000);
    view.onmouseover=function () {
      clearInterval(intervalo);
    }
    view.onmouseout=function () {
      intervalo=setInterval(toggle.rightToggle,3000);
    }
  </script>
</body>
</html>

View Code

五、一些总结

在SlidingMenu中,做出如下处理

1、本次采用了面向对象和封装的思路,这是因为个人体会到确实面向对象的设计能使代码编写思路更加清晰,还能够免去很多冗余重复的代码,也尝试过其他书写思路,但都会使代码变得不太直观;要注意的一点就是封装后要向外提供接口,且如果是封装在一个函数中,需要实例化一个对象才能调用;

9159.com 89159.com 9

2、在.slide中设置了一个内联样式,这是因为在后面要获取并改变它的left属性,如果不采用内联样式的方法,将无法设置;因为初始时.style.left只能获取内联样式,即使采用内部样式和外部样式也会使得获取的值为undefined。当然,肯定也可以采用其他方法,但是似乎其他方案都更为复杂一些,没找到更简便的方法。

public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (MyApplication.mRollViewPagerTouching){
            return false;
        }
        return super.onInterceptTouchEvent(ev);
    }

3、在前后各多放置一张图片的作用:
比如,当前是图片1,现在向左切换,可以和其他位置一样先执行统一的左移操作,这时视窗显示额外放置的图片5,再将.slide整体左移使真正的图片5显示在视窗中,这样是先出现了动画效果再“暗中移动”了.slide,就好像没移动一样,真正做到了无缝切换,逻辑也很简单;如果不放置额外的图片,就需要先将视窗左移,使图片5显示在视窗中,这样动画效果难以设置。

View Code

4、在获取每个span在它父元素的索引位置时,采用了getAttribute获取自定义的index属性的方法,其他方法肯定也有不少,但是肯定不能在循环中把i的值直接当成span的索引位置。

 

5、在跳转功能中,如果要跳转的正是当前的页面,应该什么也不做,这样可以优化性能 。

重新编译运行,可以正常滑动轮播图,但是当轮播图在第一张时,不能滑到侧滑菜单。

6、在点击左右箭头切换时,先判断上一次动画是否完成,没完成就不切换,这样可以优化性能,否则连续点击可能导致卡顿、切换效果不佳。

 

7、代码似乎还有可以优化的地方;

现在来做第二个功能:当轮播图在第一张时,可以滑到侧滑菜单。

8、这个只是制作了一个轮播图,接下来考虑做一个轮播组件,似乎难度要大些,还有3D的轮播效果也想要尝试下了。

这里有两个地方要注意:1.当轮播图在第一张时;2.由于我的侧滑菜单是在左边,需要手指向右滑动进入侧滑菜单,所以,第二个条件,应该是右滑。

PS:感兴趣的朋友还可以将上述代码中的图片替换成网络图片,再使用如下在线工具在线测试运行效果:

在以上的基础上,修改自定义ViewPager代码

HTML/CSS/JavaScript代码运行工具

9159.com 109159.com 11

在线HTML/CSS/JavaScript前端代码调试运行工具

public boolean dispatchTouchEvent(MotionEvent ev) {
        //在触发时回去到起始坐标
        float x = ev.getX();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_MOVE:
                //获取到距离差
                float dx = x - downX;
                //防止是按下也判断
                if (Math.abs(dx) > 8) {
                    //通过距离差判断方向
                    if (dx > 0) {
                        //                                "右";
                        if (getCurrentItem() == 0) {
                            MyApplication.mRollViewPagerTouching = false;
                        } else {
                            MyApplication.mRollViewPagerTouching = true;
                        }
                    } else {
                        //                                "左";
                        MyApplication.mRollViewPagerTouching = true;
                    }
                }
                break;
            case MotionEvent.ACTION_DOWN:
                //将按下时的坐标存储
                downX = x;
                MyApplication.mRollViewPagerTouching = true;
                break;
            case MotionEvent.ACTION_UP:
                MyApplication.mRollViewPagerTouching = false;
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript图片操作技巧大全》、《JavaScript切换特效与技巧总结》、《JavaScript运动效果与技巧汇总》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

View Code

希望本文所述对大家JavaScript程序设计有所帮助。

 

您可能感兴趣的文章:

  • JS使用tween.js动画库实现轮播图并且有切换功能
  • js原生实现移动端手指滑动轮播图效果的示例
  • JavaScript实现带有子菜单和控件的slider轮播图效果
  • 无限循环轮播图之运动框架(原生JS实现)
  • 使用html+js+css 实现页面轮播图效果(实例讲解)
  • 利用纯js + transition动画实现移动端web轮播图详解
  • JS轮播图实现简单代码
  • js实现移动端轮播图效果
  • 原生js实现轮播图的示例代码
  • js实现支持手机滑动切换的轮播图片效果实例
  • 原生JS实现的简单轮播图功能【适合新手】

再次编译运行,成功达到预期效果。

 

ps:简单的功能,简单的分享。

 

本文由9159.com发布于编程,转载请注明出处:同样打印log,三、编写思路

关键词:

上一篇:没有了
下一篇:没有了