JS进阶 | 解决JQ keyup事件延迟的问题

写在前面

  在使用keyup事件时,存在一个问题,假如想要做出类似于表单验证的demo:表单输入账号 “xxx” 后  再去ajax异步去后台数据库匹配,但是keyup事件的原理是每次键盘事件弹起就会检测,也就是输入“x”的时候就会检测,所以输入“xxx”就会使用三次ajax,这样的用户体验是不好的。再举一个例子,再用百度的时候,打开www.baidu.com 输入任意一个字符,就会自动弹出关于该字符的搜索信息,我感觉这个用户体验不好,我在输入一个字符的时候,百度搜索框下面某个新闻我很感兴趣,但是页面已经跳转,我history(-1)时,发现新闻页已经刷新了。这样我就看不到我想要看的新闻了。所以在输入“xxx”完整的字符再触发keyup事件显得比较重要。

如何实现

  这个问题就是keyup事件延迟的问题。如何实现,很简单,就是使用定时器setTimeout和event.timeStamp。假设定期器为1000ms,定时器负责1000ms后触发keyup事件,setTimeout的原理就是,把当前事件的执行结果放入事件循环中,待JS引擎空闲时再去处理执行结果。event.timeStamp是一个事件的时间戳,表示发生事件的时间和日期(从 epoch 开始的毫秒数)epoch 是一个事件参考点。在这里,它是客户机启动的时间。

  在keyup事件中引用event.timeStamp,last = event.timeStamp 

  在定时器中进行判断 if(last==event.timeStamp) 为真 则执行ajax

  原理就是,last代表最后一次keyup的时间戳,你停止输入1000ms内没有再次触发keyup事件,则执行ajax,用代码表示就是(last==event.timeStamp)为真,如果你1000ms又触发了keyup事件,则继续判断,如果你停止输入1000ms内没有再次触发keyup事件,则执行ajax。

  用代码完成

  js: 

// <input type="text" id="input">    
    $(function(){
        $("#input").focus();
        $("#input").on("keyup",function(e){
            $this = $(this);
            last = e.timeStamp;            
            setTimeout(function(){
            // console.log(e.timeStamp);
            var $data_data = $this.val();
                if(last-e.timeStamp===0){
                    $.ajax({
                        type:"get",
                        url:"ajaxkeyup.php",
                        data:{
                            $data:$data_data
                        },
                        success:function(data){
                            console.log("ajax发送并接收响应成功显示的ok");
                            console.log(data);

                        },
                        onerror:function(){
                            console.log("not ok");
                        }
                    })
                }
            },1000)
        })
    })

  php:

<?php 
    $data = '123';
    $getData = $_GET['$data'];
    if ($getData==$data) {
        echo "后台检测匹配失败显示的ok";
    }else{
        echo "后台检测匹配失败显示的failed";
    }
 ?>

  模拟数据库的数据为“123”,完整输入“123”后 执行ajax

  demo如下

  有点不清晰,但是效果就是当输入"123"时 触发keyup事件,执行ajax,显示ajax发送并接收成功,后台服务器也返回成功

  当输入“1234”时,ajax发送并接收成功,但是后台检测失败

总结

  这个问题是面试商汤科技呗问的问题,上一个被问的问题是promise实现红绿灯,这个问题是keyup事件的延迟。都使用了异步的操作方式,蚂蚁金服面试的时候也问JS有哪些异步操作,看来异步操作是JS的核心之一。

   分析JS异步操作

  定时器setTimeout与异步ajax同时执行,既有页面无刷新的魅力也有事件循环的感觉。爽。

  

  

  

  

  

  

posted @ 2017-08-31 11:36  dirk_jian  阅读(3264)  评论(1编辑  收藏  举报