JSのアンチシェイクとスロットリングについて
序文:手ぶれとスロットルを理解する前に、フォーカスイベントとキーボードイベントを理解しましょう
1.フォーカスイベント(フォーカス、ぼかし、入力)
- FocusEvent
フォーカスイベントは、主にフォーム要素とハイパーリンクに使用されます。クリックまたはタブを使用して、フォーカス距離を切り替えることができます。入力フォーカスがトリガーされると、フォーカスが失われたときにフォーカスがトリガーされます。
- foucsは焦点距離の焦点距離です
- ぼかしが焦点を失う
- イベントオブジェクトのrelatedTargetは、フォーカスを失った最後のオブジェクトです
<form>
<input type="text">
<input type="checkbox">
<input type="checkbox">
<select>
<option>aaaa</option>
<option>bbb</option>
<option>aaaa</option>
<option>aaaa</option>
<option>aaaa</option>
</select>
</form>
<a href="#">超链接</a>
<script>
var form=document.querySelector("form");
var input=document.querySelector("input");
input.addEventListener("focus",focusHandler);
input.addEventListener("blur",focusHandler);
// 获取单选按钮
var checkboxs=document.querySelectorAll("[type=checkbox]");
for(var i=0;i<checkboxs.length;i++){
checkboxs[i].addEventListener("focus",focusHandler)
}
// 获取下拉列表
var select=document.querySelector("select");
select.addEventListener("focus",focusHandler);
//获取超链接
var a=document.querySelector("a");
a.addEventListener("focus",focusHandler)
function focusHandler(e){
console.log(e.target,e);
if(e.type==="focus"){
e.target.style.outline="1px solid purple"
e.target.style.outlineOffset="0px";
}else if(e.type==="blur"){
e.target.style.outline="1px solid rgba(255,0,0,0)";
e.target.style.outlineOffset="5px";
}
}
</script>
デフォーカスとフォーカスは、フォームの検証を判断するために主に使用されます
// input 输入事件主要用于文本框和多行文本框
var input=document.querySelector("input");
input.addEventListener("input",inputHandler);
function inputHandler(e){
console.log(e);
// e.data: "s" 本次输入的内容
// e.isComposing: false 输入法是否启动
// e.inputType 输入的类型
// insertCompositionText 输入插入
// historyUndo 历史返回
// insertText 插入文本
// deleteContentBackward 退格删除(删除前一个)
// deleteContentForward delete删除(删除后一个)
// deleteByCut 剪切删除
// insertFromPaste 粘贴插入
}
2番目に、KeyboardEventキーボードイベント
<div></div>
<script>
var bool=false
// 按键是侦听document
document.addEventListener("keydown",keyHandler);
document.addEventListener("keyup",keyHandler);
// keydown不单纯在按下时存在,一直按着也会触发
function keyHandler(e){
if(e.type==="keydown"){
// 希望在什么地方加开关,这个开关指锁定这个位置
if(!bool){
console.log(e.type,e.keyCode);
}
bool=true;
return;
}else{
bool=false;
}
console.log(e.type,e.keyCode);
// e.code: "KeyJ" 键名
// key: "j" 键名
// keyCode: 74 键码
// which 键码
// 左 上 右 下 37,38,39,40
}
1.スロットル
テキストボックスを入力した場合、毎回入力すると判定されてしまうと効率が悪くなりすぎるので、毎回確認させていただきます。これは、イベントを継続的にトリガーすることを意味しますが、関数をn秒に1回だけ実行します。
実施原則
入力の属性を設定します。イベントが初めてトリガーされると、属性値はfalseになり、次に実行され、500ミリ秒後に入力の値が取得され、idの値が削除されます。2番目の入力が500ミリ秒に達していない場合、Idsがtrueの場合、値を取得せずに直接ジャンプします。500ミリ秒で、関数は1回だけ実行されます。
スロットリングタイマーの書き込み:
<input type="text" name="text" id="user">
<script>
init();
function init(){
var user=document.getElementById("user");
user.addEventListener("input",inputHandler);
}
function inputHandler(e){
//判断,如果input.ids为false,则往下执行
if(this.ids) return;
//500毫秒后,执行showValue函数,同时删除ids的值
this.ids=setTimeout(function(elem){
//因为定时器函数会改变this指向,这里将this以参数的形式传进来
clearTimeout(elem.ids);
elem.ids=null;
showValue(elem.value);
},500,this);
}
//打印出input的值
function showValue(txt){
console.log(txt);
}
</script>
タイムスタンプ書き込みの抑制:
<input type="text" name="text" id="user">
<script>
init();
function init() {
var user = document.getElementById("user");
user.addEventListener("input", inputHandler);
}
var lastTime=0;
function inputHandler(e) {
//每次触发事件获取当前时间
let nowTime=new Date().getTime();
//若时间间隔大于500毫秒,则执行代码
if(nowTime-lastTime>500){
//重新计时
lastTime=nowTime;
showValue(this.value);
}
}
//打印出input的值
function showValue(txt) {
console.log(txt);
}
</script>
2.ぶれ防止
アンチシェイクとは、トリガーイベントからn秒以内に関数を1回だけ実行できることを意味します。イベントがn秒以内に再度トリガーされると、関数の実行時間が再計算されます。
キーダウンイベントは、キーボードが押されたときにトリガーされます。キーボードが常に押されている場合、このイベントは常にトリガーされます。イベントがトリガーされ続けるので、関数を頻繁に実行する必要はありません。この場合、アンチシェイクはより良いソリューションです。
===実現原理:
キーダウンイベントが継続的にトリガーされる場合、イベントハンドラーは、キーの押下を500ミリ秒間停止した後に一度だけ呼び出されます。つまり、キーダウンイベントの継続的なトリガー中にイベントハンドラー関数ハンドルが実行されていません。
スロットルとアンチシェイクは似ています。上記のスロットリングに基づいて、次のコードを作成する必要があります
<input type="text" name="text" id="user">
<script>
init();
function init() {
var user = document.getElementById("user");
user.addEventListener("input", inputHandler);
}
var ids=null;
function inputHandler(e) {
//每次输入,把前面的定时器清除,重新开启定时器
if(ids !== null) clearTimeout(ids);
ids=setTimeout(function(){
showValue(this.value);
},500)
}
//打印出input的值
function showValue(txt) {
console.log(txt);
}
</script>
===手ぶれ防止パッケージ:
function debounce(fn, wait) {
var timeout = null; //定义一个定时器
return function () {
if (timeout !== null)
clearTimeout(timeout); //清除这个定时器
timeout = setTimeout(fn, wait);
}
}
// 处理函数
function handle() {
console.log(Math.random());
}
// 侦听事件
document.addEventListener("keydown", debounce(handle, 1000));
防振とスロットルの違いは?
- スロットリングとは、間隔を置いて実行するように複数の実行を変更することです
- アンチシェイクは、複数の実行を最後の実行に変えることです