开发移动触屏网页时遇到过哪些坑,解决方案是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开发移动触屏网页时遇到过哪些坑,解决方案是啥?相关的知识,希望对你有一定的参考价值。

参考技术A

开发过程中遇到无数坑,这些都是血泪史啊。很多东西只能自己经历一遍,然后才能从中有所收获。


    QQ浏览器

在QQ浏览器中,input输入框,name等于“num”,浏览器会自动设置一个值3或4,input上的value也不能起什么作用;各种检查了半天,也没发现到底是什么问题,最后才发现QQ浏览器的问题,当然也可能跟版本及系统有关,但是我没验证过其他版本的QQ浏览器。

解决办法:只要把name改一个名字就可以啦。

    三星自带浏览器

作为屏幕截图,在弹出窗口的“否”按钮下有一个“取消”按钮,点击“取消订单”按钮后弹出窗口就会出现。在“否”按钮上,它绑定单击事件,然后单击后关闭弹出窗口。如果我们将订单列表页滚动到目标浏览器上的一个特殊位置,我们将单击“取消”按钮以在窗口上闪烁bug。这个特殊位置是窗口上的“否”按钮的位置,该按钮位于“取消订单”按钮上。

解决办法将弹出按钮的单击事件为一个touchend事件,在点击touchend触发,没有延迟300ms,即使touchend将引发新创建的DOM节点,但是由于新的DOM节点的创作时间比touchend引发了很长一段时间,所以在创建节点touchend已经结束了。

    离线缓存

有的时候离线缓存,并且更新成功了,但是依然看不到,只有刷新一下才能显示。

解决办法:思路是主动帮用户刷新一次页面就好了,写个全局的方法,监听updateready后。

    最后

许多问题其实没有我们想的那么复杂,遇到问题要多思考,多问问前辈,他们的经验往往是别的地方学不到,却又十分有用的。


 



参考技术B

科技的研发过程中肯定会遇到这样那样的问题,正因为这样那样的问题才能使我们开发出来的软件更加的完美。


    第一个

技术开发肯定会遇到一些问题,这都是很正常的,只有慢慢改进,才能接近完美。tap点击问题,现在就两种解决方案,一个是单击,另一个是使用touchstart触摸和touchend事件操作,阻止touchstart 的事件冒泡 和 默认事件,再有问题,就只能 施展 奇技淫巧 比如 下面点一层 菊花层 div 然后点完之后 再隐藏。。

    第二个

动画白屏是常见的问题,听说是帧速的问题。有 就是 dom 操作 闪屏问题,这个还没有好的解决方案,目前只是做了一些dom的缓存操作,但是 iPhone5s 里面 还是有问题。

    第三个

android浏览器touchmove和touchend事件是否可能引发的问题,原因是触发touchcancel touchmove,之后的事件就阻止了,网上使用event.preventDefault()的解决方式不适用,可以在touchstart事件回调中添加延时器主动调用touchmove回调函数

    总结

当我们解决了一系列的问题之后,就会特别的开心,不是因为自己有多伟大,而是因为自己又进步啦!

移动端PC端 网页特效

移动端网页特效

触屏事件

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

touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。

常见的触屏事件:

触摸事件对象(TouchEvent)

TouchEvent 是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等

touchstart、touchmove、touchend 三个事件都会各自有事件对象。

触摸事件对象常见对象列表:

因为平时都是给元素注册触摸事件,所以重点记住 targetTocuhes

移动端拖动元素JS代码实现:

// (1) 触摸元素 touchstart:  获取手指初始坐标,同时获得盒子原来的位置
// (2) 移动手指 touchmove:  计算手指的滑动距离,并且移动盒子
// (3) 离开手指 touchend:
var div = document.querySelector('div');
var startX = 0; //获取手指初始坐标
var startY = 0;
var x = 0; //获得盒子原来的位置
var y = 0;
div.addEventListener('touchstart', function(e) {
    //  获取手指初始坐标
    startX = e.targetTouches[0].pageX;
    startY = e.targetTouches[0].pageY;
    x = this.offsetLeft;
    y = this.offsetTop;
});

div.addEventListener('touchmove', function(e) {
    //  计算手指的移动距离: 手指移动之后的坐标减去手指初始的坐标
    var moveX = e.targetTouches[0].pageX - startX;
    var moveY = e.targetTouches[0].pageY - startY;
    // 移动我们的盒子 盒子原来的位置 + 手指移动的距离
    this.style.left = x + moveX + 'px';
    this.style.top = y + moveY + 'px';
    e.preventDefault(); // 阻止屏幕滚动的默认行为
});

classList属性

classList属性是HTML5新增的一个属性。返回元素的类名,该属性用在元素中添加、移除及切换CSS类

<style>
        .bg {
            background-color: black;
        }
</style>

<body>
    <div class="one two"></div>
    <button> 开关灯</button>
    <script>
        // classList 返回元素的类名
        var div = document.querySelector('div');
        // console.log(div.classList[1]);
        // 1. 添加类名  是在后面追加类名不会覆盖以前的类名 注意前面不需要加.
        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>
</body>

常用开发插件

移动端 要求的是快速开发,所以经常会借助于一些插件来帮完成操作

JS 插件是 js 文件,它遵循一定规范编写,方便程序展示效果,拥有特定功能且方便调用。如轮播图和瀑布流插件

插件的使用:

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

特点: 它一般是为了解决某个问题而专门存在,其功能单一,并且比较小。比如移动端常见插件:iScroll、Swiper、SuperSlider

PC端网页特效

偏移量系列 offset

offset 翻译过来就是偏移量, 使用 offset 系列相关属性可以 动态 的得到该元素的位置(偏移)、大小等。

  • 获得元素距离带有定位父元素的位置
  • 获得元素自身的大小(宽度高度)
  • 注意: 返回的数值都不带单位

常用属性:

图示:

offset与style区别:

offsetstyle
可以得到任意样式表中的样式值只能得到行内样式表中的样式值
offset系列获得的数值是没有单位的style.width 获得的是带有单位的字符串
offsetWidth 包含padding+border+widthstyle.width 获得不包含padding和border 的值
offsetWidth 等属性是只读属性,只能获取不能赋值style.width 是可读写属性,可以获取也可以赋值
获取元素大小位置,用offset更合适元素更改值,则需要用style改变

案例——获取鼠标在盒子内的坐标:

效果展示:

实现代码(JS):

// 在盒子内点击, 想要得到鼠标距离盒子左右的距离。
// 首先得到鼠标在页面中的坐标( e.pageX, e.pageY)
// 其次得到盒子在页面中的距离(box.offsetLeft, box.offsetTop)
// 用鼠标距离页面的坐标减去盒子在页面中的距离, 得到 鼠标在盒子内的坐标
var box = document.querySelector('.box');
box.addEventListener('mousemove', function(e) {
	// console.log(e.pageX);
	// console.log(e.pageY);
	// console.log(box.offsetLeft);
	var x = e.pageX - this.offsetLeft;
	var y = e.pageY - this.offsetTop;
	this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;
})

案例——模态拖拽框:

  • 点击弹出层, 会弹出模态框, 并且显示灰色半透明的遮挡层。
  • 点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层。
  • 鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动。
  • 鼠标松开,可以停止拖动模态框移动。

效果展示:

实现代码:

<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .login-header {
            width: 100%;
            text-align: center;
            height: 30px;
            font-size: 24px;
            line-height: 30px;
        }
        
        ul,li,ol,dl,dt,dd,div,p,span,h1,h2,h3,h4,h5,h6,a {
            padding: 0px;
            margin: 0px;
        }
        
        .login {
            display: none;
            width: 512px;
            height: 280px;
            position: fixed;
            border: #ebebeb solid 1px;
            left: 50%;
            top: 50%;
            background: #ffffff;
            box-shadow: 0px 0px 20px #ddd;
            z-index: 9999;
            transform: translate(-50%, -50%);
        }
        
        .login-title {
            width: 100%;
            margin: 10px 0px 0px 0px;
            text-align: center;
            line-height: 40px;
            height: 40px;
            font-size: 18px;
            position: relative;
            cursor: move;
        }
        
        .login-input-content {
            margin-top: 20px;
        }
        
        .login-button {
            width: 50%;
            margin: 30px auto 0px auto;
            line-height: 40px;
            font-size: 14px;
            border: #ebebeb 1px solid;
            text-align: center;
        }
        
        .login-bg {
            display: none;
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0px;
            left: 0px;
            background: rgba(0, 0, 0, .3);
        }
        
        a {
            text-decoration: none;
            color: #000000;
        }
        
        .login-button a {
            display: block;
        }
        
        .login-input input.list-input {
            float: left;
            line-height: 35px;
            height: 35px;
            width: 350px;
            border: #ebebeb 1px solid;
            text-indent: 5px;
        }
        
        .login-input {
            overflow: hidden;
            margin: 0px 0px 20px 0px;
        }
        
        .login-input label {
            float: left;
            width: 90px;
            padding-right: 10px;
            text-align: right;
            line-height: 35px;
            height: 35px;
            font-size: 14px;
        }
        
        .login-title span {
            position: absolute;
            font-size: 12px;
            right: -20px;
            top: -30px;
            background: #ffffff;
            border: #ebebeb solid 1px;
            width: 40px;
            height: 40px;
            border-radius: 20px;
        }
    </style>
</head>

<body>
    <div class="login-header"><a id="link" href="javascript:;">点击,弹出登录框</a></div>
    <div id="login" class="login">
        <div id="title" class="login-title">登录会员
            <span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
        </div>
        <div class="login-input-content">
            <div class="login-input">
                <label>用户名:</label>
                <input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
            </div>
            <div class="login-input">
                <label>登录密码:</label>
                <input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
            </div>
        </div>
        <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
    </div>
    <!-- 遮盖层 -->
    <div id="bg" class="login-bg"></div>
    <script>
        // 1. 获取元素
        var login = document.querySelector('.login');
        var mask = document.querySelector('.login-bg');
        var link = document.querySelector('#link');
        var closeBtn = document.querySelector('#closeBtn');
        var title = document.querySelector('#title');
        // 2. 点击弹出层这个链接 link  让mask 和login 显示出来
        link.addEventListener('click', function() {
                mask.style.display = 'block';
                login.style.display = 'block';
            })
        // 3. 点击 closeBtn 就隐藏 mask 和 login 
        closeBtn.addEventListener('click', function() {
                mask.style.display = 'none';
                login.style.display = 'none';
            })
        // 4. 开始拖拽
        // (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
        title.addEventListener('mousedown', function(e) {
            var x = e.pageX - login.offsetLeft;
            var y = e.pageY - login.offsetTop;
            // (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
            document.addEventListener('mousemove', move)

            function move(e) {
                login.style.left = e.pageX - x + 'px';
                login.style.top = e.pageY - y + 'px';
            }
            // (3) 鼠标弹起,就让鼠标移动事件移除
            document.addEventListener('mouseup', function() {
                document.removeEventListener('mousemove', move);
            })
        })
    </script>
</body>

可视区系列 client

client 翻译过来就是客户端,使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

常用属性:

client和offset最大的区别就是 :不包含边框
图示:

滚动系列 scroll

scroll 翻译过来就是滚动的,使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。

常用属性:

图示:

滚动条:

  • 如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。
  • 当滚动条向下滚动时,页面上面被隐藏掉的高度,称为页面被卷去的头部。
  • 滚动条在滚动时会触发 onscroll 事件。

案例——固定右侧侧边栏:

  • 原先侧边栏是绝对定位
  • 当页面滚动到一定位置,侧边栏改为固定定位
  • 页面继续滚动,会让 返回顶部显示出来

效果展示:

实现代码:

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .slider-bar {
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        }
        
        .w {
            width: 1200px;
            margin: 10px auto;
        }
        
        .header {
            height: 150px;
            background-color: purple;
        }
        
        .banner {
            height: 250px;
            background-color: skyblue;
        }
        
        .main {
            height: 1000px;
            background-color: yellowgreen;
        }
        
        span {
            display: none;
            position: absolute;
            bottom: 0;
        }
    </style>
</head>

<body>
    <div class="slider-bar">
        <span class="goBack">返回顶部</span>
    </div>
    <div class="header w">头部区域</div>
    <div class="banner w">banner区域</div>以上是关于开发移动触屏网页时遇到过哪些坑,解决方案是啥?的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发中遇到过的坑

微信小程序使用ucharts时遇到的一些坑及其解决方案(持续更新)

移动端WEBAPP开发遇到的坑,以及填坑方案!持续更新~~~~

Kotlin 怎么学 ?遇到过哪些坑?

移动端触屏click点击事件延迟问题,以及tap的解决方案

移动端开发必会出现的问题和解决方案