Cet article vous présente principalement les informations pertinentes sur l'utilisation du défilement pour surveiller le redimensionnement dans JS. L'article le présente en détail à travers l'exemple de code. Il a une certaine valeur d'apprentissage de référence pour les études ou le travail de tous les amis qui en ont besoin. un coup d'oeil ci-dessous.
Préface
Tout le monde sait que l'événement de redimensionnement natif ne peut agir que sur le defaultView, c'est-à-dire la fenêtre, alors quelle méthode devons-nous utiliser Pour surveiller les changements de taille d’autres éléments ? L'auteur a récemment découvert une méthode magique pour implémenter indirectement la surveillance de l'événement resize via l'événement scroll. Cet article analysera le principe et l'implémentation du code de cette méthode.
Principe
Tout d'abord, jetons un coup d'œil à ce que fait l'événement scroll.
L'événement scroll est déclenché lorsque la vue du document ou un élément a défilé.
L'événement scroll est déclenché lorsque la vue du document ou un élément a défilé.
C'est-à-dire que cet événement sera déclenché lorsque l'élément défilera. Alors, quand l'élément défilera-t-il ? Un élément peut défiler lorsqu'il est plus grand que son élément parent et que l'élément parent lui permet de défiler. En d’autres termes, les éléments qui peuvent défiler signifient que les éléments parents et enfants n’ont pas la même taille, ce qui est au cœur de cette approche.
Ensuite, nous devons modifier scrollLeft ou scrollTop lorsque la taille de l'élément change, déclenchant ainsi l'événement scroll et sachant en outre que sa taille a changé.
Écoutez l'élément devenir plus grand
Lorsque l'élément devient plus grand, nous pouvons voir plus et sa zone de défilement interne diminuera lentement Petit, mais cela ne modifiera pas la position de la barre de défilement, mais lorsque l'élément est suffisamment grand pour faire disparaître la barre de défilement, cela fera que scrollLeft ou scrollTop deviendra 0, nous savons donc que l'élément est devenu plus grand, donc nous en fait, il suffit de 1px. Pour en juger, l'icône est la suivante :
L'élément d'écoute devient plus petit
Lorsque l'élément devient plus petit, la zone de défilement deviendra plus grande et la position de la barre de défilement ne changera pas réellement. L'approche adoptée ici consiste à réduire la zone de défilement et l'élément parent selon un certain rapport. et laissez l'élément parent presser et faire défiler la zone, modifiant ainsi indirectement la taille de la barre de défilement scrollLeft ou scrollTop. La description textuelle n'est peut-être pas très claire :
<.>
Grâce aux deux méthodes ci-dessus, nous pouvons obtenir l'événement de redimensionnement.Mise en œuvre
Tout d'abord, afin de ne pas affecter l'élément d'origine, nous devons créer un élément aussi grand que l'élément à surveiller, et il effectue des opérations associées, puis nous avons besoin de deux éléments enfants pour surveiller les deux situations où l'élément devient plus grand et l'élément devient respectivement plus petit. Ainsi, la structure HTML suivante est construite :<p class="resize-triggers"> <p class="expand-trigger"> <p></p> </p> <p class="contract-trigger"></p> </p>
.resize-triggers { visibility: hidden; opacity: 0; } .resize-triggers, .resize-triggers > p, .contract-trigger:before { content: " "; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > p { overflow: auto; } .contract-triggers:before { width: 200%; height: 200%; }
doivent rester 1px plus grandes que l'élément parent, et les deux .expand-triggers
déclencheurs doivent rester dans le coin inférieur droit. Par conséquent, nous pouvons implémenter l'état suivant. réinitialiser la fonction et l'initialiser Et appelé à chaque fois qu'un événement de défilement se produit :
/** * 重置触发器 * @param element 要处理的元素 */ const resetTrigger = function(element) { const trigger = element.resizeTrigger; // 要重置的触发器 const expand = trigger.firstElementChild; // 第一个子元素,用来监听变大 const contract = trigger.lastElementChild; // 最后一个子元素,用来监听变小 const expandChild = expand.firstElementChild; // 第一个子元素的第一个子元素,用来监听变大 contract.scrollLeft = contract.scrollWidth; // 滚动到最右 contract.scrollTop = contract.scrollHeight; // 滚动到最下 expandChild.style.width = expand.offsetWidth + 1 + 'px'; // 保持宽度多1px expandChild.style.height = expand.offsetHeight + 1 + 'px'; // 保持高度多1px expand.scrollLeft = expand.scrollWidth; // 滚动到最右 expand.scrollTop = expand.scrollHeight; // 滚动到最右 };
/** * 检测触发器状态 * @param element 要检查的元素 * @returns {boolean} 是否改变了大小 */ const checkTriggers = function(element) { // 宽度或高度不一致就返回true return element.offsetWidth !== element.resizeLast.width || element.offsetHeight !== element.resizeLast.height; };
/** * 添加大小更改监听 * @param element 要监听的元素 * @param fn 回调函数 */ export const addResizeListener = function(element, fn) { if (isServer) return; // 服务器端直接返回 if (attachEvent) { // 处理低版本ie element.attachEvent('onresize', fn); } else { if (!element.resizeTrigger) { // 如果没有触发器 if (getComputedStyle(element).position === 'static') { element.style.position = 'relative'; // 将static改为relative } createStyles(); element.resizeLast = {}; // 初始化触发器最后的状态 element.resizeListeners = []; // 初始化触发器的监听器 const resizeTrigger = element.resizeTrigger = document.createElement('p'); // 创建触发器 resizeTrigger.className = 'resize-triggers'; resizeTrigger.innerHTML = '<p class="expand-trigger"><p></p></p><p class="contract-trigger"></p>'; element.appendChild(resizeTrigger); // 添加触发器 resetTrigger(element); // 重置触发器 element.addEventListener('scroll', scrollListener, true); // 监听滚动事件 /* Listen for a css animation to detect element display/re-attach */ // 监听CSS动画来检测元素显示或者重新添加 if (animationStartEvent) { // 动画开始 resizeTrigger.addEventListener(animationStartEvent, function(event) { // 增加动画开始的事件监听 if (event.animationName === RESIZE_ANIMATION_NAME) { // 如果是大小改变事件 resetTrigger(element); // 重置触发器 } }); } } element.resizeListeners.push(fn); // 加入该回调 } };
supprimer des événementsSurveillance :
/** * 移除大小改变的监听 * @param element 被监听的元素 * @param fn 对应的回调函数 */ export const removeResizeListener = function(element, fn) { if (attachEvent) { // 处理ie element.detachEvent('onresize', fn); } else { element.resizeListeners.splice(element.resizeListeners.indexOf(fn), 1); // 移除对应的回调函数 if (!element.resizeListeners.length) { // 如果全部时间被移除 element.removeEventListener('scroll', scrollListener); // 移除滚动监听 element.resizeTrigger = !element.removeChild(element.resizeTrigger); // 移除对应的触发器,但保存下来 } } };
Autres
Certains d'entre eux sont utilisés pour optimisation , n'affecte pas les fonctions de base, telles que la distinction entre le rendu serveur et le rendu client, le traitement spécial pour IE et la résolution de bugs sur Chrome via une animation d'opacité.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!