setTimeout之灵巧解决疑难问题-页面延迟重绘,onkeydown事件
2017-01-18 23:41

      我们大家所知道的setTimout是一个定时器,但是setTimeout在前端中还有很多用途,这些用途全是基于它的延后执行的机理的。

           input或者textarea下的光标定位代码

    

//IE下的版本
var tea=document.getElementById("txt"); 
var txt=textArea.createTextRange(); 
txt.moveEnd("character",0-tea.value.length); 
txt.select(); 
//chrome下的版本
var aCtrl = document.getElementById("txt"); 
if (aCtrl.setSelectionRange) { 
setTimeout(function() { 
aCtrl.setSelectionRange(aCtrl.value.length,aCtrl.value.length);
}, 0); 
//触发事件为focus事件

    这段代码chrome下的光标控制不是直接运行setSelectionRange,而是在setTimout 0后运行,这个代码我亲测过,如果不加setTimeout,在chrome等浏览器下是无效的。

    这个原理呢,我推测是focus事件触发以后浏览器默认会将光标设置到文字的开头的,而我们在focus事件中将光标设置到尾部,其实是起作用了,但是浏览器的focus的本身事件是在我们的focus事件之后执行的。这样就造成了我们将光标移动到文本后面,然后浏览器又给移动到前面了,所以看起来好像没起作用似的。

    而加上setTimeout后,相当于focus事件已经运行完成,浏览器将光标放到了前面,然后再查看栈中的代码时执行setTimeout的代码将光标移动到文本后面,这样我们的代码才会起作用。

    注意如果要求高,还需要给onkeyup事件,click事件也加上这个光标代码,才能保证光标按照我们所需要的在后面。

    ajax对于我们并不陌生,但是ajax有同步请求和异步请求两种请求方式,异步请求再某种程度上就相当于使用了setTimeout的作用。

    

var el=document.getElementById("info");
info.innerHTML="正在请求中..";
$.post....//ajax同步请求代码,
info.innerHTML="请求成功!";

上面这段代码在ajax同步请求的时候如果网速快,我们只会看到请求成功,根本不会出现请求中。这个是由于浏览器在重绘时,认为这两局代码可以在一起重绘,而一起重绘渲染的结果就是info中的内容跳过"请求中",直接到"请求成功!".

而如果碰到了这类问题,只要使用setTimeout就可以解决。

var el=document.getElementById("info");
info.innerHTML="正在请求中..";
setTimeout(function(){
$.post....//ajax同步请求代码,
info.innerHTML="请求成功!";
},0);

做了如上改动后,info中的文字内容就会如我们所预期的效果,因为使用了setTimeout,浏览器就会认为他们是分开进行重绘的,而不会把他们组合到一起进行重绘。

    另外在input中绑定onkeydown事件进行字数统计,这个时候我们就需要用到setTimeout才能得到我们期望的结果,下面是使用了setTimeout处理的字数统计代码

function preventinput2(event){
  var evt=window.event||event;
  var tg=evt.srcElement||evt.target;
  setTimeout(function(){
  var len=tg.value.length;
  $(".wordcount2").html("现在有"+len+"个字符");
 },0);
}

可以点击这里查看demo

这里使用setTimeout后再计算字符数,也是因为在onkeydown事件没有运行完时浏览器不知道你又没有使用类似event.preventDefault的代码来阻止字符的正常录入。而只有在onkeydown事件执行完成后才会执行浏览器的默认行为将字符录入到input框中。而我们使用setTimeout的作用就是要保证字数统计是在onkeydown事件执行完成后再去执行,之所以代码写在onkeydown事件中,是为了利用js中的变量作用域,可以方便的操作目标input对象。

结束语:

 聊做抛砖引玉,setTimeout在js中堪称神器,对于解决处理一些莫名的异常怪异现象,他就是最后的杀手锏。

原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(3540)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1