您的位置:1010cc时时彩经典版 > 1010cc时时彩客户端 > 活动端软键盘监听,虚构键盘与fixed带给移动端的

活动端软键盘监听,虚构键盘与fixed带给移动端的

发布时间:2019-08-15 13:06编辑:1010cc时时彩客户端浏览(107)

    前言

    今天来公司的主要目的就是研究虚拟键盘与fixed的问题,期间因为同事问起闭包与事件委托(阻止冒泡)相关问题,便穿插了一篇别的:

    【小贴士】工作中的”闭包“与事件委托的”阻止冒泡“,有兴趣的朋友可以去看看,因为首页只能放一篇,这个就略去了

    现在回到主要研究点,首先在移动端我们点击文本框后会出现一个虚拟键盘, 虚拟键盘让页面可视区域得到了充分利用,但是也带来了一些问题

    移动端软键盘监听(弹出,收起),及影响定位布局的问题

    前言

    过年期间在家喝酒有点厉害,刚刚来公司这边就变成“歪脖子”了,整个肩膀很疼啊,所以程序员平时要多运动才行

    开年后也很忙,一方面然后又搬了个家,另一方面最近就算有所得,都是零零碎碎,不然就是不够深入,于是就没有什么总结了

    最近在工作中碰到几个闭包的问题,虽然我对闭包了解不是太深,但是觉得还是可以拿出来说下,如果有何问题,请指正

    摘要:*因为平时搞移动端的比例多一点,做个小小的总结。虽然网上很多这方面的总结,不过还是想自己也总结一下,适合自己的才是最好的。这样也方便以后自己的查阅*

    问题源头

    移动端虚拟键盘出现的条件是:文本框(文本类)获得焦点

    但是文本框获得焦点未必会弹出键盘!!!

    收起虚拟键盘的条件是:文本框失焦

    PS:总而言之,我们认为会出现或者消失虚拟键盘的时候都可能不工作

    在移动设备上,如果文本框在上方,点击不会有什么问题:
    在设备的最下面的话,就有所不同了,整个块会上移,以将input区域显示出来

    这个时候几个棘手的问题就出现了:

    ① 虚拟键盘的出现对页面来说是不可知的,这句话的理解是:没有键盘出现事件,没有办法获取键盘高度

    ② 键盘是“贴”在了viewport上,表面上不会对dom产生“任何”影响,但是这个时候一些定位元素的表现却变得“怪异”

    比如:

    图片 1

    图片 2

    可以看到,无论淘宝或者新浪,这个问题都存在,现在比较普遍的解决方案都是:移动端不采用fixed属性

    一:移动端软键盘监听(弹出,收起)    

    闭包的产生

    function a() {
      var i = 0;
      function b() {
        console.log(i);
      }
      return b;
    }
    var c = a();
    c();
    

    一般来说,当一个函数内部匿名函数用到了自己的变量,并且这个匿名函数被返回了,这就建立了一个闭包,比如上面的代码

    这个时候,就算a调用结束被销毁,i也会存在不会消失

    当a定义时,js解释器会将函数a的作用域链设置为定义a时所在环境

    当执行a时,a会进入相应的执行环境,执行环境创建后才会有作用域scope属性,然后创建一个活动对象,然后将其置为作用域链的顶端

    现在a的作用域链就有a的活动对象以及window

    然后为活动对象加入arguments属性

    这个时候a的返回函数b的引用给了c,b的作用域链包含a的活动对象引用,所以c可以访问到a的活动对象,这个时候a返回后不会被GC

    以上便是对闭包的简单介绍,说多了就容易绕进去了,我们这里简单结束,然后进入实际的场景加以说明

     

    图片 3 图片 4

     

      参考: 链接一   链接二        

    实际场景

    viewport模板——通用

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <!-- H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 -->
    <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
     <!-- 当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari ios7.0版本以后,safari上已看不到效 -->
    <meta content="yes" name="apple-mobile-web-app-capable">
    <!-- 将网站添加到主屏幕快速启动方式,仅针对ios的safari顶端状态条的样式  可选default、black、black-translucent-->
    <meta content="black" name="apple-mobile-web-app-status-bar-style">
    <!-- 忽略将页面中的数字识别为电话号码 -->
    <meta content="telephone=no" name="format-detection">
    <!-- 忽略Android平台中对邮箱地址的识别 -->
    <meta content="email=no" name="format-detection">
    <title>标题</title>
    <link rel="stylesheet" href="style.css">
    </head>
    
    <body>
       内容
    </body>
    
    </html>
    

      

     

    window.alert = 'body').append('<div>'   msg   '</div>'(document.activeElement.nodeName == 'INPUT''position', 'static''position', 'fixed''#headerview header'500);
    

    根据测试结果来说,是满足我们的需求的,这里的header不会出问题,但是footer由于没有处理仍然会错位

    图片 5 图片 6

    于是这个问题似乎被我们修复了,但是你可以接受吗???这个方案有一个致命的恶心点!

    不停的监控dom变化,浪费资源

    setTimeout('#dl_app img'100= 'body').append('<div>'   msg   '</div>'=  i = 0  (document.activeElement.nodeName == 'INPUT''position', 'static''position', 'fixed'(window.res ) { clearInterval(window.res ); window.res  = 'input').focus((!'#headerview header'= setInterval('#headerview header'500
    

    这样的话,貌似能让代码看上去舒服一点,但是其代价却是所有input类标签都会多一个获得焦点事件,依旧令人痛惜

         1.监听resize ( Android)

    同事的疑惑

    之前一个同事让我去看一个代码:

    var User = function (opts) {
      var scope = this;
      for (var k in opts) {
          scope['get'   k] = function () {
            return opts[k];
          };
          scope['set'   k] = function (v) {
            return opts[k] = v;
          };
      }
      };
    
    var u = new User({
      name: '测试',
      age: 11
    });
    

    代码本意很简单,希望对传入的对象生成get/set方法,但是他这里就遇到一个闭包问题:

    图片 7

    导致这个问题的原因就是返回值内部使用的k永远是“age”,这个k便是由于getXXX函数共享的活动对象,这里修改也比较简单

    var User = function (opts) {
      var scope = this;
      for (var k in opts) {
        (function (k) {
          scope['get'   k] = function () {
            return opts[k];
          };
          scope['set'   k] = function (v) {
            return opts[k] = v;
          };
        })(k);
      }
    };
    
    var u = new User({
      name: '测试',
      age: 11
    });
    

    在for循环内部创建一个立即执行函数,将k传入,这个时候getXXX函数共享的就是各个匿名函数的“k”了

    移动端字体font-family

    body {font-family: "Helvetica Neue", Helvetica, STHeiTi, sans-serif;}
    

      

     

    结语


    今天来公司的主要目的就是研究虚拟键盘与fixed的问题,期间因为同事问起闭包与事件委托(阻止冒泡)相关问题,便穿插了一篇别的...

    var winHeight = $(window).height();  //获取当前页面高度
    $(window).resize(function () {
        var thisHeight = $(this).height();
        if ( winHeight - thisHeight > 140 ) {
            //键盘弹出
        } else {
            //键盘收起
        }
    })
    

    生成唯一ID

    生成唯一ID也是闭包一个经典的使用方式

    function getUUID() {
      var id = 0;
      return function () {
        return   id;
      }
    }
    var uuid = getUUID();
    

    这段代码其实非常有意义,我们在浏览器中不停的执行uuid()确实会得到不同的值,但是如果我们只使用getUUID()()的话每次值仍然一样

    图片 8

    导致这个问题的原因是,我们将getUUID执行后的结果赋予uuid,这个时候uuid就保存对其中匿名函数的引用,而匿名函数保存着getUUID的活动对象,所以id一直未销毁

    而直接调用的话,每次都会重新生成活动对象,所以id是不能保存的

    css3多文本换行,最后省略为 ...

    图片 9

    p {
        overflow : hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
    

     

      140是一个预估值的阀值,用来排除其他的resize操作。仅resize的高度差大于140时,才被识别为软键盘交互,否则不是。如浏览器的工具栏、搜索栏的隐藏,window的窗口页会有一个较小的变化。

    一段有意思的代码

    Util.tryUrl = function (url) {
      var iframe = document.createElement('iframe');
      iframe.height = 1;
      iframe.width = 1;
      iframe.frameBorder = 0;
      iframe.style.position = 'absolute';
      iframe.style.left = '-9999px';
      iframe.style.top = '-9999px';
      document.body.appendChild(iframe);
    
      Util.tryUrl = function (url) {
        iframe.src = url;
      };
    
      U.tryUrl(url);
    };
    

    这段代码十分有意思,当我们第一次调用时候会创建一个iframe对象,而第二次调用时候iframe对象就存在了,我们这里将代码做一定简化后

    var getUUID = function () {
      var i = 0;
      getUUID = function () {
        return i  ;
      };
      return getUUID();
    };
    

    这样调整后,其实并不存在返回函数,但是我们其实依然形成了闭包

    解决ios下输入框为fixed的乱位

    在ios里面,当一个文本框的样式为fixed时候,如果这个文本框获得焦点,它的位置就会乱掉,由于ios里面做了自适应居中,这个fixed的文本框会跑到页面中间。类似:

    图片 10(请原谅盗图,我错了)

     

    解决办法有如下两个:

    1、可以在文本框获得焦点的时候将fixed改为absolute,失去焦点时在改回fixed,但是这样会让屏幕有上下滑动的体验不太好。

    .fixfixed {
    position:absolute;
    }
    $(document)
        .on('focus', 'input', function(e) {
    
            $(this).addClass('fixfixed');
    
        })
        .on('blur', 'input', function(e) {
           $(this).removeClass('fixfixed');
        })
    

     

     2、还有一种就是用一个假的fixed的文本框放在页面顶部,一个absolute的文本框隐藏在页面顶部,当fixed的文本框获得焦点时候将其隐藏,然后显示absolute的文本框,当失去焦点时,在把absolute的文本框隐藏,fixed的文本框显示。

    .fixfixed {
    position:absolute;
    }
    $(document)
        .on('focus', 'input', function(e) {
            $absolute..show();
            $(this).hide();
        })
        .on('blur', 'input', function(e) {
             $fixed..show();
            $(this).hide();
        });
    

        2.监听input失焦blur(IOS)

    事件委托与闭包

    我们都知道jquery的on是采用的事件委托,但是真正了解什么事事件委托仍然要花一定功夫,于是我们这里来试试

    闭包是事件委托实现的基石,我们最后就以事件委托深入学习下闭包结束今天闭包的学习吧

    加入我们页面下有如下dom结构

    <input id="input" value="input" type="button" />
    <div id="div">
      我是div</div>
    我是span
    <div id="wrapper">
      <input id="inner" value="我是inner" type="button"/>
    </div>
    

    我们使用zepto的话是使用如下方式绑定事件

    $.on('click', 'selector', fn)
    

    我们这里没有zepto就自己简单实现吧

     

    本文由1010cc时时彩经典版发布于1010cc时时彩客户端,转载请注明出处:活动端软键盘监听,虚构键盘与fixed带给移动端的

    关键词: