IOS11下fixed中input光标错位问题

项目遇到了这个问题,故作了个临时解决方案,暂时没有想到更好的方法,查阅了网上的方案,也没有找到完美的解决方案。

方案思路:

①弹窗打开时,阻止 body 滚动,禁用 touchmove ,同时记录当前 body 的滚动高度 startScrollTop

②弹窗关闭时,恢复 body 滚动,同时给当前滚动条赋值 startScrollTop ,恢复到弹窗前的高度

③关闭输入键盘时,同样恢复到弹窗前的高度

实现的代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ios11光标错位问题</title>
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
    <style type="text/css">
        .wrap{
            height: 4000px;
        }
        button{
            margin-bottom: 1000px;
            display: block;
        }
        .fixed{
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 2;
            box-sizing: border-box;
            background: rgba(0,0,0,0.2);
        }
        .mask{
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(255,0,0, 0.1);
            z-index: 1;
        }
        input{
            padding: 10px;
        }
        .abs{
            width: 200px;
            padding: 10px;
            position: absolute;
            z-index: 99;
            border: 3px solid #000;
            background: #fff;
        }
    </style>
</head>
<body>
    <h2>顶部</h2>
    <div class="wrap">
        <button type="button" name="button" onclick="showDialog()">show dialog</button>
        <button type="button" name="button" onclick="showDialog()">show dialog</button>
        <button type="button" name="button" onclick="showDialog()">show dialog</button>
    </div>
    <div class="fixed" id="dialog" style="display: none;">
        <div class="mask" onclick="hideDialog()"></div>
        <div class="abs">
            <div><input type="text" onfocus="getDialogScrollTop()" onblur="setDialogScrollTop()" name="" value=""></div>
            <div><input type="text" onfocus="getDialogScrollTop()" onblur="setDialogScrollTop()" name="" value=""></div>
            <div><input type="text" onfocus="getDialogScrollTop()" onblur="setDialogScrollTop()" name="" value=""></div>
        </div>
    </div>
    <h2>底部</h2>
<script>
    var startScrollTop = 0;

    function showDialog() {
        document.getElementById('dialog').style.display = "flex";
        disabledScroll()
        getDialogScrollTop();
        setDialogScrollTop();
    }

    function hideDialog() {
        document.getElementById('dialog').style.display = "none";
        enabledScroll()
    }

    // 取消默认事件
    function stopPreventDefault(e) {
            e.preventDefault();
            e.stopPropagation();
    }

    // 添加 touchmove 事件 禁用滚动条滚动
    function disabledScroll() {
        document.addEventListener("touchmove", stopPreventDefault, false);
    }

    // 取消 touchmove 事件 还原滚动条滚动,同时还原小键盘打开前的滚动高度
    function enabledScroll() {
        document.removeEventListener("touchmove", stopPreventDefault);
        setTimeout(setDialogScrollTop, 200)
    }

    // 获取当前滚动高度并赋值到 startScrollTop
    function getDialogScrollTop() {
            startScrollTop = document.body.scrollTop;
    }

    // 还原滚动高度
    function setDialogScrollTop() {
        document.querySelectorAll('.fixed').forEach(function(ths) {
            ths.style.top = startScrollTop + 'px';
        });
        document.body.scrollTop = startScrollTop
    }
</script>
</body>
</html>
原文地址:https://www.cnblogs.com/marunzhou/p/8466074.html