11月15, 2017

搜索sug中踩的坑

背景是这样的,最近开发一个查询地址的sug功能,即监控输入框的变化,一但变化可以通过API查询该关键字,将结果列出在下面供用户选择。接下来说一下开发过程中遇到的两个坑。

一、函数Debounce

虽说只是监控变化,就发起请求。但是如果用户输入特别快,特别频繁。比如一秒内按了10几个字母(可能单身很多年了),然后还一通乱按。接下来你就会发现你的控制台多了一连串的相同请求(都是sug请求),这是一个非常恐怖的事情,如果用户一多,后台挂掉也就是分分钟的事情了。

大量网络请求

所以我们期望用户输入已经完成或者等待的时候才发起查询。这两种情况下,用户都会停止输入,这个时候可以在用户停止后200ms后进行查询。

使用防抖动(Debounce)可以解决这个问题,防抖动的意思是:只有时间间隔大于一定值的时候才会执行该函数。最简单的思路是:在主体函数里面使用定时器,某个时间段(比如200ms)后执行,但是每次调用的时候都先清除前一个定时器,确保永远只有一个定时器且该定时器或在指定时间后执行。代码如下:

const delay = 200;
let timer = void 0;

function requestData(keyword){
    if(timer) clearTimeout(timer);

    timer = setTimeout(function(){
        /*$ajax({
            ...
        });*/
    }, delay);
}

类似场景还有:

  • 鼠标移动,mousemove 事件
  • window对象的resize和scroll 事件

同样都可以使用防抖动(Debounce)的思路来解决只需要获取最后状态的问题。与之类似的还有函数节流(Throttle),跟防抖动(Debounce)类似,但又有不同,有兴趣的可以了解下。

二、中文输入法下的input事件误触发

开发过程中发现一个奇怪的情况,在手机上某些情况下点选下面sug结果进行选择的时候会再触发一次查询,导致sug列表没有正确关闭。
没有截图,用两个其他的图表示一下现场,发生原因是:手机上使用中文输入法是输入诸如gn的拼音,再去点选sug结果,这个时候输入法失去焦点,自动将中文的g'n转化为了英文状态下的gn,会额外再触发一次查询,而且该查询的关键字与上次查询一致。

输入法

suglist

解决办法:

存储每次查询的关键字,每次查询前都判断是否与上次查询的关键字一致,一致则不进行查询。

let prevWord = '';

requestData(keyword){
    if( (prevWord || keyword) && prevWord === keyword) return;

    prevWord = keyword;
    //...
}

本文链接:https://luodao.me/post/sug-cai-keng.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。