Maison > Article > interface Web > Troisième sujet JavaScript : Anti-tremblement
Table des matières
Écrit à la fin
(Recommandations d'apprentissage gratuites associées : tutoriel vidéo javascript)
1. Pourquoi l'anti-tremblement est nécessaire
À cette fin, prenons un exemple de code pour comprendre comment l'événement se déclenche fréquemment :
Nous écrivons un fichier index.html :
<meta> <meta> <meta> <title>Document</title> <title>debounce</title> <style> #wrapper { width: 100%; height: 200px; line-height: 200px; text-align: center; color: #fff; background-color: #444; font-size: 30px; } </style> <p></p> <script> var count = 1; var op = document.getElementById("wrapper"); function getUserAction() { op.innerHTML = count++; } op.onmousemove = getUserAction; </script>
Il se déclenche près de 100 fois en glissant de gauche à droite getUserAction
Fonction ! Regardez le Gif suivant :
Comme cet exemple est très simple, le navigateur peut réagir complètement, mais supposons :
Ce type d'interaction qui met trop de pression sur le navigateur ou le serveur en peu de temps doit être optimisé. Afin de résoudre ce problème, il existe généralement deux solutions :
Réduire la fréquence de déclenchement d'une fonction pour améliorer les performances ou éviter le gaspillage de ressources.
2. Le principe de l'anti-shake
Aujourd'hui nous allons nous concentrer sur la mise en place de l'anti-shake. Le principe de l'anti-shake est le suivant : même si vous déclenchez un événement, je ne l'exécuterai pas tant que l'événement ne se déclenchera pas. Par exemple : n秒无操作后
est la norme pour l'anti-shake, puis : 3s
3. Implémentez un anti-shake par vous-même
3.1 Première éditionNous Sur la base des idées de base mentionnées dans la section précédente, implémentez la première version du code :function debounce(func, wait) { var timer; return function () { clearTimeout(timer) timer = setTimeout(func, wait); }}Si nous voulons l'utiliser, prenons l'exemple de la première section à titre d'exemple :
op.onmousemove = debounce(getUserAction, 2000);A ce stade vous pouvez le tester à nouveau. Désormais, lorsque l'événement continue de se produire, l'événement ne se déclenchera qu'après 2 secondes d'arrêt complet : En écrivant ceci, comme exigence pour certains événements à haute fréquence, c'est terminé. Jetons un coup d'œil à son effet : 3.2 Deuxième édition Comme nous le savons tous, lorsqu'un nœud dom déclenche un événement, celui-ci pointe vers lui-même. Dans cet exemple, il pointe vers
, mais dans ce cas : Jetons un coup d'œil à op
var count = 1;var op = document.getElementById("op");function getUserAction() { op.innerHTML = count++; console.log('this', this); // 此时输出 Window...}op.onmousemove = debounce(getUserAction, 2000);function debounce(func, wait) { var timer; return function () { clearTimeout(timer) timer = setTimeout(func, wait); }}Après tout, il a été enveloppé par une couche de fonctions anonymes. Cela pointe déjà vers window In. afin de réduire l'impact, nous essayons de le corriger
function debounce(func, wait) { var timer; return function () { var _this = this; // 记录当前this clearTimeout(timer) timer = setTimeout(function(){ func.apply(_this); //将 func的this改为_this }, wait); }}La troisième version résout ce problème de pointage Notre fonction n'est toujours pas assez "parfaite" En JavaScript, la fonction de traitement des événements. fournira l'objet
, que nous appelons e en abrégé. event
// 使用了 debouce 函数function getUserAction(e) { console.log(e); // undefined op.innerHTML = count++;};Afin de garantir son authenticité, nous allons modifier la troisième version :
var count = 1;var op = document.getElementById("op");function getUserAction(e) { op.innerHTML = count++; console.log('e', e); // MouseEvent}op.onmousemove = debounce(getUserAction, 2000);function debounce(func, wait) { var timer; return function () { var _this = this; // 记录当前this var arg = arguments; // 记录参数 clearTimeout(timer) timer = setTimeout(function () { func.apply(_this, arg); //将 func的this改为_this }, wait); }}Jusqu'à présent, nous avons ajouté à la fonction tout en conservant autant que possible les capacités originales de l'événement Dom . Avec l'effet anti-secousse, cela peut résoudre la plupart de nos problèmes anti-secousses de développement quotidien, mais nous devons être plus "parfaits"
4. Anti-tremblement avancé
4.1 Exécuter immédiatementCette exigence est :n
n
pour déterminer s'il est exécuté immédiatement. immediate
function debounce(func, wait, immediate) { var timer; return function () { var _this = this; var args = arguments; if (timer) clearTimeout(timer); // 常规流程,间隔内触发时清掉重置定时 if (immediate) { // 如果已经执行过,不再执行 var callNow = !timer; // 1. callNow 初始值是 true, 同步立即执行;随后 timer 才开始执行 timer = setTimeout(function(){ timer = null; // wait 期间,timer 是一个 ID 数字,所以 callNow 为 false,func 在此期间永远不会执行 }, wait) // wait 之后,timer 赋值 null,callNow 为 true,func 又开始立即执行。 if (callNow) func.apply(_this, args) } else { timer = setTimeout(function(){ func.apply(_this, args) }, wait); } }}Jetons un coup d'œil à son effet à ce moment : 4.2 Ajouter une vérification simple
function debounce(func, wait, immediate) { var timer; // 检查函数 if (typeof func !== 'function') { throw new TypeError('Expected a function'); } // 保证wait存在 wait = +wait || 0; const debounced = function () { var _this = this; var args = arguments; if (timer) clearTimeout(timer); // 常规流程,间隔内触发时清掉重置定时 if (immediate) { // 如果已经执行过,不再执行 var callNow = !timer; // 如果不存在定时器,则callNow为true timer = setTimeout(function () { timer = null; // 为了保证之后的时效性,手动添加timer }, wait) // 因为不存在timer,证明是首次执行,所以直接调用 if (callNow) func.apply(_this, args) } else { timer = setTimeout(function () { func.apply(_this, args) }, wait); } } return debounced}
function debounce(func, wait, immediate) { var timer; // 检查函数 if (typeof func !== 'function') { throw new TypeError('Expected a function'); } // 保证wait存在 wait = +wait || 0; const debounced = function () { var _this = this; var args = arguments; if (timer) clearTimeout(timer); // 常规流程,间隔内触发时清掉重置定时 if (immediate) { // 如果已经执行过,不再执行 var callNow = !timer; // 如果不存在定时器,则callNow为true timer = setTimeout(function () { timer = null; // 为了保证之后的时效性,手动添加timer }, wait) // 因为不存在timer,证明是首次执行,所以直接调用 if (callNow) func.apply(_this, args) } else { timer = setTimeout(function () { func.apply(_this, args) }, wait); } } const cancel = function(){ clearTimeout(timer); timer = null; } const pending = function(){ return timer !== undefined; } debounced.cancel = cancel; debounced.pending = pending; return debounced}
rrreee
Regardons l'effet : a écrit Même si cette méthode simple anti-tremblement est correcte, elle n'est en effet pas parfaite. Si vous avez des suggestions d'amélioration, veuillez laisser un message dans la zone de commentaire~.Recommandations d'apprentissage gratuites associées : javascript (vidéo)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!