移动端常见问题梳理

2,303 阅读6分钟

本文是最近一段时间开发移动端项目所遇到的一些问题已经解决方法,现在做如下梳理。

1、安卓机 设置 宽高0.2rem, border-radios:50% 圆会变形

原因:安卓对rem/em 单位支持不好,改为px即可

<p className="tag">
    <span className="txt”>按钮</span>
</p>
.tag{
    display: flex;
    float: right;
    text-align:center;
    align-items:center;
    justify-content:center;
    width: 2rem;
    height: .8rem;
    .txt{
        display: inline-block;
        white-space: nowrap;
        font-size: 1rem; // 将字体放大两倍,字体和行高最好是偶数
        transform: scale(0.5); // 再缩小
    }
}

2、判断Android和IOS

// 判断安卓
export const isAndroid = () => {
    let ua = navigator.userAgent.toLowerCase();
    return ua.indexOf('android') > -1 || ua.indexOf('linux') > -1;
}
// 判断IOS
export const isIOS = () => {
    return /(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent);
}

3、软键盘相关

if (isIOS()) {
    document.body.addEventListener('focusout', () => { //软键盘关闭事件
    window.scrollTo({ top: 10, left: 0, behavior: "smooth" })//重点 =======当键盘收起的时候让页面回到原始位置
    })
}
  • Android 不遮挡最下面按钮,收回后会回到顶部,但是如果页面高度不够,软键盘+吸底按钮会遮挡最下面的输入框,并且需要定位光标到某个输入框的位置
if (isAndroid()) {
    window.addEventListener("resize", () => {
        setTimeout(() => {
            document.activeElement.scrollIntoViewIfNeeded(); // 定位光标到输入位置
            this.setState({
                className: 'hight-wrap’ // 吸底按钮遮挡需要增加页面高度
            })
        }, 0);
    })
}

.hight-wrap{
    height: 24rem;
}

4、body的overflow:hidden;在移动端失效

document.body.style.position='fixed’;  // 设置
document.body.style.position='static’; // 恢复

或者:但是感觉效果不好
html, body{
    height:100%;
    overflow:hidden;
}

5、移动端Android字体偏上问题

// 父元素
{
    display: flex;
    align-items: center;
    justify-content: center;
}
// 子元素
{
    transform: scale(0.5);
    transform-origin: left center;
    // 进行缩放,再同等倍数的对元素放大,可以达到相对的居中。
}

6、移动端滚动卡顿问题

流畅滚动的N条军规:
1. body上加上 -webkit-overflow-scrolling: touch
2. iOS尽量使用局部滚动
3. iOS引进scrollFix避免出界
4. android下尽量使用全局滚动:
    * 尽量不用 overflow:auto
    * 使用min-height:100% 替代 height:100%;
5. iOS下带有滚动条且position: absolute 的节点不要设置背景色

7、html2Canvas转换海报问题

1)文字竖版 writing-mode: vertical-lr; 对于数字英文会错乱

2)用其他方式实现文字竖版:

实现原理:把一段话的每一个字放在一个span标签中(文字比较多可以通过 js 生成span),然后把这些span标签放在一个大的div容器中,将容器div顺时针旋转90度,然后将容器中的span逆时针旋转90度,经过两次旋转之后就达到了竖排文字的需求,标点符号不旋转

<style>
 .container {
        position: absolute;
        right: 300px;
        margin-top: -200px;
        width: 440px;
        height: 1000px;
        background-color: #FFFFFF;
        padding-left: 36px;
        font-family: "楷体";
        border: 1px solid #999999;
        margin-left: 100px;
        overflow-y: scroll;
        overflow-x:hidden;
        -webkit-transform: rotate(90deg);
    }
    
    /**每一行的容器(竖列)**/
    .container .items {
        width: 445px;
        height: 34px;
        /*background-color: #EEEEEE;*/
        /*border-left: 1px solid #999999;*/
    }
    
    .container .items .item {
        display: inline-block;
        width: 20px;
        height: 20px;
        font-size: 20px;
        text-align: center;
        line-height: 20px;
        /*border-bottom: 1px solid #CCCCCC;*/
    }
    
    .container .items .item:hover {
        background-color: pink;
        cursor: pointer;
        font-size: 22px;
    }
    
    .action1 {
        width: 100px !important;
        padding-left: 20px;
    }
    
    .rotate {
        -webkit-transform: rotate(-90deg);
    }
    
    .style1 {
        background-color: #ff6699;
        color: #EEEEEE;
    }
    
    .style2 {
        background-color: #4c98ce;
        color: #EEEEEE;
    }
    
    #vertical div {
        width: 1.5em;
        float: right;
    }
    
    #vertical .title {
        font-size: xx-large;
        font-weight: bold;
        line-height: 1em;
    }
</style>

<div class="container">
        <p> </p>
        <div class="items">              
            <div class="item"></div>          
            <div class="item"></div>
            <div class="item"></div>
            <div class="item rotate" style="font-size:36px;font-weight:bold;">爱</div>     
            <div class="item"></div>
            <div class="item rotate" style="font-size:36px;font-weight:bold;">莲</div> 
            <div class="item"></div>
            <div class="item rotate" style="font-size:36px;font-weight:bold;">说</div>
             <div class="item"></div>   
            <div class="item"></div>
            <div class="item"></div>         
            <div class="item"></div>
            <p> </p>
        </div>
        <p class='action1'></p>
    </div>

<!--引入jquery依赖-->
<script src="jquery.min.js"></script>
<script>
 var arr = "水陆草木之花,可爱者甚蕃。晋陶渊明独爱菊。自李唐来,世人甚爱牡丹。予独爱莲之出淤泥而不染,濯清涟而不妖,中通外直,不蔓不枝,香远益清,亭亭净植,可远观而不可亵玩焉。予谓菊,花之隐逸者也;牡丹,花之富贵者也;莲,花之君子者也。噫!菊之爱,陶后鲜有闻。莲之爱,同予者何人?牡丹之爱,宜乎众矣!".split("");

    var cHeight = $(".items").height();

    var textHeight = $(".item").height();

    var vCount = parseInt(cHeight / textHeight); //每列显示的字数

    var textArr = [];
    for (var i = 0; i < arr.length; i++) {
        if (i % 20 == 0) {
            textArr.push({
                "hanzi": arr[i]
            });
        } else {
            textArr[textArr.length - 1].hanzi += arr[i];
        }
    }

    var html = "";
    for (var j = 0; j < textArr.length; j++) {
        html += "<div class='items'>";
        var tempArr = textArr[j].hanzi.split("");
        console.log(tempArr)
        for (var k = 0; k < tempArr.length; k++) {
           if(/[<>《》!*(^)$%~!@#$…&%¥—+=、。,;‘’“”:·`]/.test(tempArr[k])){
                html += "<div class='item' style='display:inline'>" + tempArr[k] + "</div>";
            } else {
                html += "<div class='item rotate'>" + tempArr[k] + "</div>";
            }
        }
        html += "</div>";
    }
    
    $(".action1").after(html);
</script>
  • ②用flex布局,也是每个生产p或者span标签,父容器设置固定的宽度,让文字超过高折行
.wrap{
    width: .9rem;
    height: 18rem;
    color: white;
    font-size: .75rem;
    padding-left: .2rem;
    display: flex;
    flex-direction: column;
    flex-wrap: wrap-reverse;
    /* line-height: 0.90rem; */
    /* writing-mode: vertical-lr; */
    .items{
        width: .75rem;
        text-align:center;
    }
}

8、img撑满全屏的方法

div img{
    width: 100%;
    height: 100%;
    object-fit:cover;
}

9、阻止浮动卡片滑动时穿透,引起卡片下方页面滑动

let carddom = ReactDOM.findDOMNode(this.card); // 获取卡片的dom节点
carddom.addEventListener('touchmove', (e) => { 
    e.preventDefault(); // 阻止默认事件
});

10、底部输入框软键盘顶起后,点击「发送」按钮不生效

  • Ios和安卓通用解决方案:
// 点击发送时发送消息,click无法触发「发送」事件,移动端改用touchstart可触发
let btndom = ReactDOM.findDOMNode(this.btn); // 获取按钮dom
btndom.addEventListener('touchstart', (e) => { // 将click事件改为监听touchstart
    e.preventDefault(); // 可以阻止软键盘关闭
    _this.handlerSubmit();
})
  • 安卓:可以在点击事件时加setTimeout延时触发,也可以触发点击事件

11、组件销毁清除定时器依然报警告[Can't perform a React state update on an unmounted component],通过变量控制

componentDidMount() {
    this._isMounted = true; // 判断组件是否卸载
}
// 监听滚动事件
handlerScroll = () => {
    // 组件卸载后不执行,解决警告[Can't perform a React state update on an unmounted component]
    if (this._isMounted) {
        this.setState({ isScroll: true })
    }
}
componentWillUnmount() {
    this._isMounted = false;
}

12、video自动播放:

1. ios 触发自动播放时阻止全屏,需要增加属性:

webkit-playsinline="isiPhoneShowPlaysinline"playsInline=“isiPhoneShowPlaysinline"

<video id=“test" src="test.mp4"
    webkit-playsinline="isiPhoneShowPlaysinline" 
    playsinline="isiPhoneShowPlaysinline" 
    autoplay="autoplay" 
    controls="controls"
></video>

2. ios 或者 android 在微信内置浏览器中不会自动播放,autoplay属性不生效解决办法:

document.addEventListener('WeixinJSBridgeReady',function(){
    document.getElementById('test').play()
},false);