fredshare / blog

护卫银河
https://fredshare.github.com/blog/
112 stars 23 forks source link

移动端前端常见bug及解决方案 #21

Open fredshare opened 9 years ago

fredshare commented 9 years ago
body { -webkit-text-size-adjust : none; -ms-text-size-adjust : none; }
a { background-color : transparent; }
WP手机:<meta name="msapplication-tap-highlight" content=“no”/>
Webkit:a { -webkit-tap-highlight-color : transparent; }
img { -webkit-touch-callout : none; }
input { -webkit-appearance : none; }

内容垂直居中一般用于弹出层,如果尺寸固定的话,用CSS绝对定位就可以搞定,但是如果尺寸是不固定的,就需要使用js动态定位。 其实在移动端还可以使用display:box;就可以轻松的让内容垂直居中,如下:

<div class="box">
    <div class="content">
        <p>我是内容-1</p>
        <p>我是内容-2</p>
    </div>
</body>
<style>
.box {
    width:800px;height:600px;background:red;
    display : -webkit-box;
    -webkit-box-orient : horizontal;
    -webkit-box-pack : center;
    -webkit-box-align : center;
    display : -moz-box;
    -moz-box-orient : horizontal;
    -moz-box-pack : center;
    -moz-box-align : center;
}
</style>

在IOS系统中,当我们点击输入框拉起虚拟键盘的时候,默认情况下对于英文输入法键盘是开启了首字母大写功能的。但是在我们项目里面为了更好的体验需要默认将该特性去掉。此时,可以使用移动webkit浏览器支持的特性将其去除:在input元素上添加autocapitalize属性。通过使用autocapitalize="off"来关闭默认虚拟键盘首字母大写。如果要开启,可以使用 autocapitalize="on"。

<div class="ui-searchbar-input"><input value="" type="text" placeholder="请输入游戏名称" autocapitalize="off"></div>

IOS下,输入英文情况下,回退清除字符不会触发keypress事件,android下可以。此外,IOS下切换为中文输入法时候,输入过程中输入框对产生的字母会响应keypress,但是对于单击选择中文到输入框后后不会触发keypress事件。以此类推,剩下的keyDown、keyUp事件都差不多。 总结:keyPress之类的键盘事件监听不适合移动端的虚拟键盘监听,总是会引发这种或者那种问题。

在手机上实时捕获用户输入搜索框的内容明显跟PC有区别的,最大的不同就是PC有实体键盘,而移动web捕获的是虚拟键盘。既然键盘事件不行,那么我们就从Input元素输入框入手,看看有什么事件可以利用。 onpropertychange事件:该事件是IE浏览器特供,只要当前对象属性发生改变(例如输入框文案),都会触发事件,webkit就忽略吧。 onchange事件: webkit可以用,但是只有当当前元素失去了焦点后,才会去校验属性是否有更改,才会触发这个事件(也就是说一直输入内容是不会触发该事件的,也许select元素标签适合这个特性),明显不符合用户输入体验。 oninput事件: chrome webkit也可以使用,IE9+也可使用。也是表示输入时候内容一旦有变更就实时触发,而且不会受限于必须失去焦点才会触发的制约。

oninput事件bugfix总结: 1、在IOS下,输入中文点击选择后会连续触发两次oninput事件,android下我使用的机型未出现该问题 2、在IOS下,中文输入法输入英文时候,字母之间会出现一个类似于空格的东东,研究了一下这种空格可以称之为“六分之一空格”

/**
 * 对于用户在Input框里面的输入进行过滤,例如 1、对于IOS六分之一空格情况 2、对于IOS输入中文时候会连续两次触发onInput情况
 * 
 * @param str {String} 从input框读取的值
 * @returns {String} 返回过滤后的值
 * 
 */
function filterString(str) {
    if (!isAndroid) {
        // IOS下需要做的处理
        var cache = arguments.callee;
        var curTime = new Date().getTime() / 1000;
        // 当前搜索的字符串在这个delta
        // ms时间区间里面如果跟最近的一次搜索字符串相同,则不对该结果进行响应,解决情况2问题
        var delta_time = 400;
        // 保存当前的字符串信息
        var keyObj = {
            str : str,
            time : curTime
        };

        if (cache.keyObj && cache.keyObj.str == str) {
            // 读取最近一次的字符串信息
            var lastTime = cache.keyObj.time;
            if (curTime - lastTime < delta_time) {
                // 此时可认为丢弃此次相同关键字查找
                return "";
            }
            // 重新更新cache
            cache.keyObj = keyObj;
        } else {
            // 这是新开页面的第一次成功检索或者和最近一次检索的字符串是不一样的关键字
            // 更新cache
            cache.keyObj = keyObj;
        }

        // 接着进行六分之一空格的处理
        str = str.replace(/\u2006/g, "");
    }

    return str;

}

vm和vh:这两种单位是以视窗(viewpoint)的宽度和高度为基准,1vw = 1/100 视窗宽度,1vh = 1/100 视窗高度,举个栗子:如果浏览器的视窗宽高分别为1000px和900px,那么1vw = 1000/100 = 10px、1vh = 900/100 = 9px。如果想让一个元素占据全屏,你可以这样:

<div class="content">
    <h2>标题文字</h2>
    <p>我是内容-1</p>
    <p>我是内容-2</p>
</body>
<style>
*{margin:0;padding:0;}
.box {
    position:absolute;top:0;left:0;background:red;
    width: 100vw;
    height: 100vh;
}
</style>

vmin:vmin的值是当前vw和vh中较小的值。 vmax:vmax的值是当前vw和vh中较大的值。

darren562 commented 8 years ago

请教一下:移动端 自己写的一个autocomplete 调用的是oninput 事件,在中文键盘下,我先输入字母这个时候还没有选择中文,我的autocomplete 已经出来了查询结果。这个时候点击某一个结果集,没有触发结果集的click,而是把我的把我的虚拟键盘隐藏,这个问题怎么解决?在英文输入法下没有问题。

hoverCow1990 commented 6 years ago

字符监听那个,我把onchange和onblur一起加上就好了,本来我那个也是明明输入框里是中文提交上去的变拼音了,我也是醉了

CracKerMe commented 6 years ago

@darren562 你解决 这个 键盘在弹起状态下 点击事件无效的问题了么?我现在 也遇到了 类似的问题,请指教如何解决的