移动web——touch事件应用

基本概况

1、touch事件在移动端被用来代替click事件,因为click事件的触发会延迟影响了用户体验

2、touch事件还可以与translate构成吸附效果

3、现行有一种排版方式是左边宽度是固定的,右边是自适应的

4、下面通过一个项目串联起来这些知识点,顺便说下移动端静态页面设置技巧

左定宽右适应

1、左边div设置宽高和浮动,右边内容不用设置宽高,直接overflow属性设置成hidden就可以了,如果不设置此属性,就文本绕图了

2、不管你如何横向拉伸浏览器,右边都能够自适应

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Title</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        html, body {
            width: 100%;
            height: 100%;
        }

        div:nth-child(1) {
            width: 50px;
            height: 200px;
            background-color: #ccc;
            float: left;
        }

        div:nth-child(2) {
            overflow: hidden;
        }
    </style>
</head>
<body>
<div></div>
<div>
    哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
</div>
</body>
</html>

input标签自适应

1、如何input标签自适应,而不让两边的标签自适应,并且永远处于两边

2、首先左右两边标签是定位到各自位置,因为是定位所以不占位置。通栏的左右padding宽度各自取值到定位标签的宽度就行了,帮他们占位。

3、input标签宽度100%,继承通栏宽度,这样浏览器横向不管如何拉伸input标签都是自适应的

4、需要注意的是移动开发box-sizing属性设置的是border-box,下面如果不这样设置,input继承的宽100%并不是div原来的100%宽度减去padding的值,而是固定的content增加了padding,值依然不会变

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>Title</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            -webkit-box-sizing: border-box;
            box-sizing: border-box;
        }

        html, body {
            height: 100%;
            overflow: hidden;
        }

        div {
            width: 100%;
            height: 40px;
            background-color: #cccccc;
            position: relative;
            padding-right: 50px;
            padding-left: 50px;

            line-height: 40px;
        }

        div span:nth-child(1) {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 50px;
            text-align: center;
            line-height: 40px;
            background-color: yellow;
        }

        div span:nth-child(3) {
            position: absolute;
            top: 0px;
            right: 0px;
            width: 50px;
            text-align: center;
            line-height: 40px;
            background-color: yellow;
        }

        div input {
            width: 100%;
            height: 25px;
            border-radius: 5px;
        }
    </style>
</head>
<body>
<div>
    <span>占位左</span>
    <input type="search" placeholder="请搜索">
    <span>占位右</span>
</div>
</body>
</html>

touch模仿click事件

1、之前我们对touch事件进行了封装,那么我们如何具体应用呢?

2、在我们自己封装的fox_tap方法回调函数中,我们能够拿到此次点击的event对象,里面有我们需要的target属性,看看谁是触发者,然后利用这个触发者做一些文章,这和冒泡事件中的模态框案例是一样的原理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        html, body {
            height: 100%;
        }

        div {
            width: 50px;
            height: 100%;
        }

        div ul {
            list-style: none;
            width: 100%;
        }

        div ul li {
            float: left;
            text-align: center;
            width: 100%;
            height: 40px;
            line-height: 40px;
            border: 1px solid #cccccc;
        }

        .current {
            background-color: red;
        }
    </style>
</head>
<body>
<div>
    <ul>
        <li><a href="#">选择1</a></li>
        <li><a href="#">选择2</a></li>
        <li><a href="#">选择3</a></li>
        <li><a href="#">选择4</a></li>
    </ul>
</div>
<script>
    var liArr = document.querySelectorAll('div ul li');
    for (var i = 0; i < liArr.length; i++) {
        fox_tap(liArr[i], function (e) {
            console.log(e.target.tagName);
            if (e.target.tagName == "A") {
                for (var j = 0; j < liArr.length; j++) {
                    liArr[j].className = '';    
                }
                e.target.parentNode.className = 'current';
            }
        })
    }

    /*
        element:绑定的dom元素
        callback:回调函数
    */
    function fox_tap(element, callback) {
        var statTime = 0;
        var isMove = false;
        var maxTime = 250;
        var event = null;
        element.addEventListener('touchstart', function (e) {
            statTime = Date.now();
            /*
                每次执行注册事件都要初始化此值,因为touchmove事件触发的时候会更改isMove的值,不更改,
                下次再进入touchtend事件会沿用上次touchmove修改过的isMove的值,这样就一直终端函数
            */
            isMove = false;
            event = e;
        });
        element.addEventListener('touchmove', function (e) {
            isMove = true;
        });
        element.addEventListener('touchend', function (e) {
            if (isMove == true) {
                return;
            }
            if ((Date.now() - statTime) > maxTime) {
                return;
            }
            callback(event);
        });
    }
</script>
</body>
</html>

 touch吸附效果

1、需求解释:所谓吸附效果其实就是我们使用手机的时候经常遇到的效果,手指按住屏幕往上或往下滑动很深的位置,所选择的区域只能往上或往下移动到一个最大范围,超过这个范围就不会再移动,随后手指移开,所选择区域会缓动的方式归位。

2、核心思想:

(1)以touchstart事件作为开始,touchmove事件不断触发作为动力,遇到最大范围,就不准再移动,区域永远定格在最大范围上;除了最大范围,中间的区域是自由移动的。

(2)以touchend事件作为结束,来计算手指离开屏幕的时候是否需要启动缓慢的归位的效果,往下滑动,只要moveDistance>0就需要归位,往上滑动,只要当moveDistance < -(Math.abs(cha))就需要归位,其他范围都是自由移动不需要归位。

(3)还有需要注意的是,归位之后,区域的移动的坐标就需要重新赋值了,没有归位的属于自由移动的也需要重新赋值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Title</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        html, body {
            width: 100%;
            height: 100%;
        }

        div {
            width: 100px;
            height: 100%;
            overflow: hidden;
        }

        ul {
            list-style: none;
            width: 100%;
        }

        li {
            width: 100%;
            height: 60px;
            text-align: center;
            line-height: 60px;
            border: 1px solid #000;
        }
    </style>
</head>
<body>
<div>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
        <li>11</li>
        <li>12</li>
        <li>13</li>
        <li>14</li>
        <li>15</li>
        <li>16</li>
        <li>17</li>
    </ul>
</div>
<script>
    var div = document.querySelector('div');
    var ul = document.querySelector('ul');
    var divH = div.offsetHeight;
    var ulH = ul.offsetHeight;
    var cha = ulH - divH;//这是ul比div大的差值
    var range = 100;//这是移动的范围值
    var maxRange = -(Math.abs(cha) + range);

    var startY = 0;
    var moveY = 0;
    var distance = 0;
    ul.addEventListener('touchstart', function (e) {
        ul.style.transition = '';
        startY = e.touches[0].clientY;
    });
    ul.addEventListener('touchmove', function (e) {
        //每次移动都会触发touchmove事件,意味着每次都会更新translate的值
        moveY = e.touches[0].clientY - startY;

        //当往下拖动的距离大于range时,我们将ul定死在range上
        //当往上拖动的距离大于maxRange时,我们将ul定死在maxRange上
        //其他范围,ul都可以自由上下移动
        var moveDistance = distance + moveY;
        if (moveDistance >= range) {
            ul.style.transform = 'translateY(' + range + 'px)';
        } else if (moveDistance <= maxRange) {
            ul.style.transform = 'translateY(' + maxRange + 'px)';
        } else {
            ul.style.transform = 'translateY(' + moveDistance + 'px)';
        }
    });
    //touchend事件就需要开始我们的吸附效果
    //1、当ul在touchmove事件中移动的距离大于0,我们就将他归位,别忘了归完之后需要将distance重新赋值
    //2、当ul在touchmove事件中移动的距离小于-(Math.abs(cha)),我们就将其归位到-(Math.abs(cha))位置
    ul.addEventListener('touchend', function (e) {
        var moveDistance = distance + moveY;
        if (moveDistance >= 0) {
            ul.style.transition = 'all .5s';
            ul.style.transform = 'translateY(0px)';//回归原位
            distance = 0;
        } else if (moveDistance < -(Math.abs(cha))) {
            ul.style.transition = 'all .5s';
            ul.style.transform = 'translateY('+(-(Math.abs(cha)))+'px)';//回归原位
            distance = -(Math.abs(cha));
        } else {
            distance = moveDistance;
        }
    });
</script>
</body>
</html>

原文地址:https://www.cnblogs.com/wuqiuxue/p/8252996.html