JavaScript基础(3)——移动端网页特效

目标及目录

在这里插入图片描述
在这里插入图片描述

触屏事件

触屏事件概述

移动端浏览器兼容性较好,所以我们不需要考虑以前JS的兼容性问题,可以放心的使用原生JS书写效果,但是移动端也有自己独特的地方,比如触屏事件touch(也称触摸事件),Android和IOS都有。

touch对象代表一个触摸点。触摸点可能是手指,也可能是触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。
在这里插入图片描述

触摸事件对象(TouchEvent)

TouchEvent 是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少等等。
touchstart、touchmove、touchend三个事件都有各自的事件对象。
触摸事件对象重点看三个常见对象列表:
在这里插入图片描述

<script>
    // 1.获取元素
    // 2. 手指触摸DOM元素事件
    var div = document.querySelector('div');
    div.addEventListener('touchstart', function (e) {
        // console.log(e);// 有很多属性,目前先了解三个 touches targetTouches changedTouches
        // touches 正在触摸屏幕的所有手指的列表 touches.length表示有几个触摸点
        // targetTouches 正在触摸当前DOM元素的手指列表
        // 如果侦听的是一个DOM元素,他们两个是一样的
        // changedTouches 手指状态发生了改变的列表 从无到有或者从有到无
        console.log(e.targetTouches[0]);
    });
    // 4. 手指离开DOM元素事件
    div.addEventListener('touchend', function (e) {
        // console.log(e);
        // 当我们手指离开屏幕的时候,就没有了touches和targetTouches列表,但会有changedTouches
    });
    // 因为我们一般都是触摸元素,所以经常使用的是targetTouches
    // console.log(e.targetTouches[0]); 可以得到正在触摸dom元素的第一个手指的相关信息,比如手指坐标
</script>
移动端拖动元素
  1. touchstart、touchmove、touchend可以实现拖动元素
  2. 拖动元素需要当前手指的坐标值,可以使用targetTouches[0]里面的pageX和pageY
  3. 移动端拖动的原理:手指移动中,计算出手指移动的距离。用盒子原来的位置+手指移动距离
  4. 手指移动的距离:手指滑动中的位置减去手指刚开始触摸的位置
  5. 手指移动的距离=盒子原来的位置+手指滑动中的位置-手指刚开始触摸的位置
    拖动元素三部曲:
  6. 触摸元素touchstart:获取手指初始坐标,同时获得盒子原来的位置
  7. 移动手指touchmove:计算手指的滑动距离,并且移动盒子
  8. 离开手指touchend
    注意:手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动e.preventDefault();
<div></div>
<script>
    // 拖动元素三部曲
    // (1)触摸手指 touchstart :获取手指初始坐标,同时获得盒子原来的位置
    // (2)移动手指 touchmove :计算手指的滑动距离,并且移动盒子
    // (3)离开手指touchend
    var div = document.querySelector('div');
    var startX = 0; // 获取手指初始坐标
    var startY = 0;
    var x = 0; // 获取盒子的初始坐标
    var y = 0;
    var moveX = 0; // 手指移动的距离
    var moveY = 0;
    div.addEventListener('touchstart', function (e) {
        // console.log(e.targetTouches[0].pageX, e.targetTouches[0].pageY);
        // console.log(div.offsetWidth, div.offsetHeight);
        startX = e.targetTouches[0].pageX;
        startY = e.targetTouches[0].pageY;
        x = div.offsetLeft;
        y = div.offsetTop;
    });
    div.addEventListener('touchmove', function (e) {
        // console.log(e.targetTouches[0].pageX, e.targetTouches[0].pageY);
        moveX = e.targetTouches[0].pageX - startX;
        moveY = e.targetTouches[0].pageY - startY;
        div.style.left = moveX + x + 'px';
        div.style.top = moveY + y + 'px';
        e.preventDefault(); // 阻止屏幕滚动的默认行为
    });
</script>

移动端常见特效

一案例:
在这里插入图片描述
在HTML中:

修改焦点图模块增加焦点图模块和小圆点模块
<!-- 焦点图模块 -->
<div class="focus">
    <ul>
        <li><img src="upload/focus1.jpg" alt=""></li>
        <li><img src="upload/focus2.jpg" alt=""></li>
        <li><img src="upload/focus3.jpg" alt=""></li>
    </ul>
    <!-- 小圆点 -->
    <ol>
        <li class="current"></li>
        <li></li>
        <li></li>
    </ol>
</div>

在CSS中:

/* 小圆点居于右下角 */
.focus ol{
    position: absolute;
    bottom: 5px;
    right: 5px;
}
/* 设置每个未选中的小圆点的宽高背景圆角 */
.focus ol li {
    display: inline-block;
    width: 5px;
    height: 5px;
    background-color: red;
    border-radius: 2px;
    list-style: none;
}
/* 更改当前选中小圆点的宽度 */
.focus ol li.current {
    width: 15px;
}

修改CSS:
根据pc端轮播图书写经验需要拿第一张图放在最后面
又因为移动端的特性,有左右拖拉的效果,所以在第一张图片前加最后一张图片

.focus ul {
    /* 清除浮动 */
    overflow: hidden;
    width: 500%;
    /* 因为加了图片在第一张前面,导致默认显示那张图片,所以移动100%的距离(父亲的宽度的100%也就是ul的)这样就显示真正的第一张图片 */
    margin-left: -100%;
}
.focus ul li {
    float: left;
    /* 将宽度缩小为父级宽度的1/5 */
    width: 20%;
}

案例分析1:

  1. 自动播放功能
  2. 开启定时器
  3. 移动端移动,可以使用translate移动
  4. 图片做优雅的移动,添加过渡效果

HTML和CSS书写完毕,现在开始书写js:

window.addEventListener('load', function () {
    // alert(1);
    // 1.获取元素
    var focus = document.querySelector('.focus');
    var ul = focus.children[0];
    // 获得focus的宽度
    var w = focus.offsetWidth;
    // 2.利用定时器自动轮播图片.
    var index = 0;
    var timer = setInterval(function () {
        index++;
        var translatex = -index * w;
        ul.style.transform = 'translateX(' + translatex + 'px)';
        ul.style.transition = 'all .3s';
    }, 2000)
})

案例分析2:

  1. 自动播放功能-无缝滚动
  2. 注意,我们判断条件是要等到图片滚动完毕再去判断,也就是过渡完成以后判断
  3. 此时需要添加检测过渡完成事件 transitionend
  4. 判断条件:如果索引号等于3则说明走到最后一张图片,此时索引号要复原为0

在这里插入图片描述

 // 等着我们过渡完成之后,再去判断监听过渡完成的事件 transitionend
 ul.addEventListener('transitionend', function () {
     if (index == 3) {
         index = 0;
         // console.log(index);
     }
 })
  1. 此时图片,去掉过渡效果,然后移动(生硬的移动过去)
在上述代码中添加:
// 去掉过渡效果 这样让我们的ul快速的跳到目标位置
ul.style.transition = 'none';
// 利用最新的索引号乘以宽度去滚动图片
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + 'px)';
  1. 如果索引号小于0,说明是倒着走,索引号等于
  2. 此时图片,去掉过渡效果,然后移动
 else if (index < 0) {
            index = 2;
            ul.style.transition = 'none';
            // 利用最新的索引号乘以宽度去滚动图片
            var translatex = -index * w;
            ul.style.transform = 'translateX(' + translatex + 'px)';
        }

控制小圆点:

  • 旧方法:通过控制自定义属性index来确定给哪个li一个current属性,清除其他的current类(操作类名)
  • 新方法:使用classList属性
classList

classList属性是HTML5新增的一个属性,返回元素的类名。但是ie10以上版本支持。该属性用于在元素总添加、移除及切换CSS类。有以下方法
添加类:

element.classList.add('类名');
focus.classList.add('current');

移除类

element.classList.remove('类名');

切换类

element.classList.toggle('类名);
<div class="one two"></div>
<button>开关灯</button>
<script>
    // classList 返回元素的类名
    var div = document.querySelector('div');
    // console.log(div.classList[0]);
    // 1.添加类名 是在后面追加类名,不会覆盖以前的类名,不同于className
    div.classList.add('three');
    //2. 移除类名
    div.classList.remove('one');
    // 3. 切换类
    var btn = document.querySelector('button');
    btn.addEventListener('click', function () {
        document.body.classList.toggle('bg');
    })
</script>

案例分析3:

  1. 小圆点跟随变化效果
  2. 把ol里面li带有current类名的选出来去掉类名remove
  3. 让当前索引号的小li加上current
  4. 但是,是等着过渡结束之后变化,所以这个写到transitionend事件里面
// 4.小圆点跟随变化效果
// 把ol里面li带有current类名的选出来去掉类名remove
ol.querySelector('.current').classList.remove('current');
// 让当前索引号的小li加入current (add方法)
ol.children[index].classList.add('current');

案例分析4:

  1. 手指滑动轮播图
  2. 本质就是ul跟随手指移动,简单说就是移动端拖动元素
  3. 触摸元素touchstart:获取手指初始坐标
  4. 移动手指touchmove:计算手指的滑动距离,并且移动盒子
// 5.手指滑动轮播图
var startX = 0; // 获取手指初始坐标


// 后面我们会使用这个移动距离所以要定义一个全局变量
var moveX = 0; // 手指移动的距离


ul.addEventListener('touchstart', function (e) {
    startX = e.targetTouches[0].pageX;
    // 手指触摸的时候就停止计时器
    clearInterval(timer);


});
ul.addEventListener('touchmove', function (e) {
    // 计算移动距离:
    moveX = e.targetTouches[0].pageX - startX;
    // 移动盒子: 盒子原来的位置+手指移动的距离
    var translatex = -index * w;
    // 手指拖动的时候,不需要动画效果所以要取消过渡效果
    ul.style.transition = 'none';
    ul.style.transform = 'translateX(' + translatex + moveX + 'px)';
});

案例分析5:

  1. 离开手指touchend:根据滑动的距离分不同的情况
  2. 如果移动距离小于某个像素,就回弹到原来的位置
  3. 如果移动距离大于某个像素,就上一张下一张的滑动
ul.addEventListener('touchend', function () {
    //(1)如果移动距离大于50px我们就播放上一张
    if (Math.abs(moveX) > 50) {
        // 右滑就是播放上一张,moveX是正值
        if (moveX > 0) {
            index--;
        }
        // 左滑就是播放下一张,moveX是负值
        else {
            index++;
        }
        var translatex = -index * w;
        ul.style.transform = 'translateX(' + translatex + 'px)';
        ul.style.transition = 'all .3s';
    }
    else {
    // (2)如果移动距离小于50px我们就回弹
    var translatex = -index * w;
    ul.style.transform = 'translateX(' + translatex + 'px)';
    ul.style.transition = 'all .3s';
}
// 手指离开的时候就重新开启定时器
clearInterval(timer);
timer = setInterval(function () {
    index++;
    var translatex = -index * w;
    ul.style.transform = 'translateX(' + translatex + 'px)';
    ul.style.transition = 'all .3s';
}, 2000);
})

如果只是点击而未移动则不需要判断回弹的位置
需写入一个全局变量flag

还要写入一个e.preventDefault();//阻止屏幕默认行为

又一案例:
在这里插入图片描述

案例分析:

  1. 滚动到某个地方显示
  2. 事件:scroll页面滚动事件
  3. 如果被卷去的头部(window.pageYOffset)大于某个值就出现
  4. 点击后,window.scroll(0,0)然后返回顶部
// 返回顶部模块制作
var goBack = document.querySelector('.goBack');
window.addEventListener('scroll', function () {
    if (window.pageYOffset >= focus.offsetHeight) {
        goBack.style.display = 'block';
    } else {
        goBack.style.display = 'none';
    }
});
goBack.addEventListener('click', function () {
    window.scroll(0, 0);
})
click 延时解决方法

移动端click事件会有300ms 的延时,原因是移动端屏幕双击会缩放(double tap to zoom)页面。
解决方案:
1.禁用缩放。浏览器禁用默认的双金缩放行为并且去掉300ms的点击延迟。

<meta name="viewport" content="user-scalable=no">

2.利用touch事件自己封装这个事件解决300ms延迟
原理:

  1. 当我们手指触摸屏幕,记录当前触摸时间
  2. 当我们手指离开屏幕,用离开的时间减去触摸的时间
  3. 如果时间小于150ms,并且没有滑动过屏幕,那么我们就定义为点击

在这里插入图片描述

移动端常用开发插件

第一种方案的缺陷:有些页面就是要求能够缩放
因此研究出第三种方案:
使用插件:fastclick插件解决300ms延迟。

什么是插件

移动端要求的是快速开发,所以我们经常会借助于一些插件来帮我们完成操作,那什么是插件呢?
JS插件就是一些js文件,它遵循一定规范编写,方便程序展示效果,拥有特定功能且方便调用。如轮播图插件和瀑布流插件。
特点:一般是为了解决某个问题而专门存在,其功能单一,并且比较小。
我们以前写的animate.js 也算一个最简单的插件

fastclick插件解决 300ms延迟。使用延时
GitHub官网地址:https://github.com/ftlabs/fastclick

引入:

<script type='application/javascript' src='/path/to/fastclick.js'></script>

使用:

if ('addEventListener' in document) {
	document.addEventListener('DOMContentLoaded', function() {
		FastClick.attach(document.body);
	}, false);
}
<style>
    div {
        width: 50px;
        height: 50px;
        background-color: pink;
    }
</style>
<script src="fastclick.js"></script>


<div></div>
<script>
    if ('addEventListener' in document) {
        document.addEventListener('DOMContentLoaded', function () {
            FastClick.attach(document.body);
        }, false);
    }
    var div = document.querySelector('div');
    div.addEventListener('click', function () {
        alert(11);
    })
</script>
Swiper插件的使用

中文官网地址:https://www.swiper.com.cn/

  1. 引入插件相关文件
  2. 按照规定语法使用

引入:解压文件后,将package中的js文件里的swiper.js和css文件夹里的swiper.css放入项目里

示例使用:
打开demos文件夹,以“030-pagination”为例
首先复制html
在这里插入图片描述
然后复制CSS:
将CSS复制进入index.css中
在这里插入图片描述
js中:
在主页中直接复制后,粘贴到index.js中:
在这里插入图片描述

window.addEventListener('load', function () {
    var swiper = new Swiper('.swiper-container', {
        pagination: {
            el: '.swiper-pagination',
        },
    });
})

引入方法:
https://www.swiper.com.cn/usage/index.html
使用方法:
https://www.swiper.com.cn/api/index.html

其他移动端常见插件
  • superslide: http://www.superslide2.com/
  • iscroll: https://github.com/cubiq/iscroll
插件使用总结
  1. 确认插件实现的功能
  2. 去官网插看使用说明
  3. 下载插件
  4. 打开demo实例文件,查看需要引入的相关文件,并且引入
  5. 复制demo实例文件中的结构html,样式css以及js代码
移动端视频插件 zy.media.js

引入css,html和js,就可实现在不同的端口不同的浏览器中播放效果相同

移动端常用开发框架

框架概述

框架,顾名思义就是一套架构,它会基于自身的特点向用户提供了一套较为完整的解决方案。框架的控制权在框架本身,使用者要按照框架所规定的某种规范进行开发。

插件一般是为了解决某个问题而专门存在的,其功能单一,并且比较小。

前端常用的框架有Vue、Angular、React等。既能开发PC端,也能开发移动端

前端常用的移动端插件有swiper、superslide、iscroll等。

总结一句话:框架——是大而全的,一整套解决方案;插件——是小而转移的,为某个功能设计的解决方案

旋转木马做轮播图
bootstrap是依赖jQuery的,因此引入bootstrap之前要先引入jQuery
在https://v3.bootcss.com/javascript/#carousel中找到

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    <script src="bootstrap/js/jquery.min.js"></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <style>
        .focus {
            width: 800px;
            height: 300px;
            background-color: pink;
            margin: 100px auto;
        }


        .carousel,
        .carousel img {
            height: 300px !important;
            width: 100%;
        }
    </style>
</head>


<body>
    <div class="focus">
        <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
            <!-- Indicators 小圆点-->
            <ol class="carousel-indicators">
                <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
                <li data-target="#carousel-example-generic" data-slide-to="1"></li>
                <li data-target="#carousel-example-generic" data-slide-to="2"></li>
            </ol>


            <!-- Wrapper for slides 轮播图片-->
            <div class="carousel-inner" role="listbox">
                <div class="item active">
                    <img src="upload/banner(1).dpg" alt="...">
                    <div class="carousel-caption">
                        pic1
                    </div>
                </div>
                <div class="item">
                    <img src="upload/banner1.dpg" alt="...">
                    <div class="carousel-caption">
                        pic2
                    </div>
                </div>
                <div class="item">
                    <img src="upload/banner2.dpg" alt="...">
                    <div class="carousel-caption">
                        pic3
                    </div>
                </div>
            </div>


            <!-- Controls 左右箭头-->
            <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
                <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                <span class="sr-only">Previous</span>
            </a>
            <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
                <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                <span class="sr-only">Next</span>
            </a>
        </div>
    </div>
    <script>
        $('.carousel').carousel({
            interval: 1000
        })
    </script>
</body>


</html>
Bootstrap

Bootstrap是一个简洁、直观、强悍的前端开发框架,它让web开发更加迅速、简单。能开发PC端,也能开发移动端。
Bootstrap JS插件使用步骤:

  1. 引入相关JS文件
  2. 复制HTML结构
  3. 修改对应样式
  4. 修改相应JS参数

引入JS和CSS文件

    首先引入js和css文件
<!-- 引入bootstrap 样式文件 -->
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    <!-- 引入我们自己的首页样式文件 -->
    <link rel="stylesheet" href="css/index.css">
    <!-- 先引入jquery js文件 -->
    <script src="bootstrap/js/jquery.min.js"></script>

然后找到轮播图的位置,将刚刚练习过的轮播图HTML放进去
然后在css中修改图片还有左右箭头的位置

.carousel,
.carousel img {
    width: 100%;
    height: 266px!important;
}

还有修改一系列相关样式

本地存储

在这里插入图片描述
在这里插入图片描述

本地存储

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变得越来越复杂,为了满足各种各样的需求,会经常性的在本地存储大量的数据,HTML5规范提出了相关的解决方案。

本地存储特性
  1. 数据存储在用户浏览器中
  2. 设置、读取方便、甚至页面刷新不丢失数据
  3. 容量较大,sessionStorage约5M、localStorage约20M
  4. 只能存储字符串,可以将对象JSON.stringify()编码后存储

window.sessionStorage

按F12,在application里面的session storage里面进行交互

步骤:

  1. 生命周期是通过关闭浏览器窗口结束
  2. 在同一个窗口(页面)下的数据可以共享
  3. 以键值对的形式存储使用
存储数据
sessionStorage.setItem(key, value)
// key是自己起的名字,value是其值
获取数据
sessionStorage.getItem(key)
删除所有数据
sessionStorage.clear()
<input type="text" name="" id="">
<button class="set">存储数据</button>
<button class="get">获取数据</button>
<button class="remove">删除数据</button>
<button class="del">清空所有数据</button>
<script>
    var ipt = document.querySelector('input');
    var set = document.querySelector('.set');
    set.addEventListener('click', function () {
        // 当我们点击了之后,就可以把表单里面的值存储起来
        var val = ipt.value;
        window.sessionStorage.setItem('uname', val);
        window.sessionStorage.setItem('mingzi', val);
    });
    var get = document.querySelector('.get');
    get.addEventListener('click', function () {
        // 当我们点击了之后,就可以得到相应的值
        sessionStorage.getItem('uname');
        sessionStorage.getItem('mingzi')
    });
    var remove = document.querySelector('.remove');
    remove.addEventListener('click', function () {
        // 当我们点击了之后,就可以删除相应的值
        sessionStorage.removeItem('uname');
    });
    var del = document.querySelector('.del');
    del.addEventListener('click', function () {
        // 当我们点击了之后,就可以删除所有的数据
        sessionStorage.clear();
    })
</script>

window.localStorage

  1. 生命周期永久有效,除非手动删除否则关闭页面也会存在
  2. 可以多窗口(页面)共享(同一浏览器可以共享)
  3. 以键值对的形式存储使用
存储数据
localStorage.setItem(key, value)
// key是自己起的名字,value是其值
获取数据
localStorage.getItem(key)
删除数据
localStorage.removeItem(key)
删除所有数据
localStorage.clear()

以上基本和sessionStorage相同

一案例:

在这里插入图片描述
案例分析:

  1. 把数据存起来,用到本地存储
  2. 关闭页面,也可以显示用户名,所以用到localStorage
  3. 打开页面,先判断是否有这个用户名,如果有,就在表单里显示用户名,并且勾选复选框
  4. 当复选框发生改变的时候change事件
  5. 如果勾选,就存储,否则就移除
用户名:
<input type="text" id="username">
<input type="checkbox" name="" id="remember">是否记住用户名
<script>
    var username = document.querySelector('#username');
    var remember = document.querySelector('#remember');
    
    if (localStorage.getItem('username')) {
        username.value = localStorage.getItem('username');
        remember.checked = true;
    }
    remember.addEventListener('change', function () {
        if (this.checked) {
            localStorage.setItem('username', username.value);
        } else {
            localStorage.removeItem('username');
        }
    })
</script>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值