이 글은 주로 JS에서 스크롤을 사용하여 크기 조정을 모니터링하는 관련 정보를 예제 코드를 통해 자세히 소개합니다. 이는 모든 사람의 학습이나 작업에 대한 특정 참조 및 학습 가치가 있습니다. 아래를 살펴보겠습니다.
머리말
네이티브 크기 조정 이벤트는 defaultView, 즉 윈도우에서만 작동할 수 있다는 사실은 누구나 알고 있는데, 다른 요소의 크기 변화를 어떻게 모니터링해야 할까요? 저자는 최근 스크롤 이벤트를 통해 resize 이벤트의 모니터링을 간접적으로 구현하는 마법 같은 방법을 발견했습니다. 이 기사에서는 이 방법의 원리와 코드 구현을 분석합니다.
Principle
먼저 스크롤 이벤트가 무엇을 하는지 살펴보겠습니다.
문서 보기나 요소가 스크롤되면 스크롤 이벤트가 시작됩니다.
문서 보기나 요소가 스크롤되면 스크롤 이벤트가 시작됩니다.
즉, 요소가 스크롤될 때 이 이벤트가 트리거됩니다. 그러면 요소는 언제 스크롤됩니까? 요소는 상위 요소보다 크면 스크롤될 수 있으며 상위 요소는 스크롤을 허용합니다. 즉, 스크롤할 수 있는 요소는 부모 요소와 자식 요소의 크기가 동일하지 않다는 것을 의미하며, 이것이 이 접근 방식의 핵심입니다.
그런 다음 요소 크기가 변경되면 scrollLeft 또는 scrollTop을 변경하여 스크롤 이벤트를 트리거하고 크기가 변경되었음을 더 자세히 알아야 합니다.
요소가 커지는 것을 들어보세요
요소가 커지면 더 많은 것을 볼 수 있고 내부 스크롤 가능 영역이 서서히 줄어들지만 이로 인해 스크롤 막대의 위치가 바뀌지는 않습니다. 요소가 커지면 더 많이 볼 수 있습니다. 요소가 너무 커서 스크롤 막대가 사라지면 scrollLeft 또는 scrollTop이 0으로 변경되므로 요소가 커졌다는 것을 알 수 있으므로 실제로 판단하는 데는 1px만 필요합니다. 아이콘은 다음과 같습니다.
요소가 작아지는 것을 듣고 있습니다.
요소가 작아지면 스크롤 가능한 영역이 커지지만 스크롤 막대의 위치는 실제로 변경되지 않습니다. 여기서 취한 접근 방식은 스크롤 가능 영역과 상위 요소를 특정 비율로 함께 축소하고 상위 요소가 스크롤 영역을 압축하도록 하여 스크롤 막대의 크기를 간접적으로 변경하는 것입니다. . 아래 그림을 살펴보겠습니다.
위의 두 가지 방법을 통해 크기 조정 이벤트를 얻을 수 있습니다.
Implementation
먼저 원본 요소에 영향을 주지 않기 위해서는 모니터링할 요소만큼 큰 요소를 생성하고 관련 작업을 수행해야 합니다. 그런 다음 두 개의 하위 요소가 필요합니다. 요소 변경 사항을 각각 모니터링하면 큰 요소와 더 작은 요소가 발생하는 두 가지 상황이 있습니다. 따라서 다음 HTML 구조가 구성됩니다.
<p class="resize-triggers"> <p class="expand-trigger"> <p></p> </p> <p class="contract-trigger"></p> </p>
해당 CSS는 다음과 같습니다.
.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%; }
.expand-triggers
의 하위 요소의 너비와 높이는 상위 요소보다 1px 더 크게 유지되어야 하며, 둘 다 Triggers는 오른쪽 하단의 상태 내에 있어야 하므로 다음과 같은 상태 재설정 기능을 구현하고 초기화 및 모든 스크롤 이벤트 중에 이를 호출할 수 있습니다.
/** * 重置触发器 * @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); // 加入该回调 } };
그리고 다음 함수를 사용하여 이벤트 리스너를 제거리스너:
/** * 移除大小改变的监听 * @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); // 移除对应的触发器,但保存下来 } } };
Others
일부 그 중 콘텐츠는 최적화를 위해 사용되며 서버 렌더링과 클라이언트 렌더링의 구분, IE에 대한 특수 처리, 불투명 애니메이션을 통한 Chrome의 버그 해결 등 기본 기능에는 영향을 미치지 않습니다.
위 내용은 JS는 스크롤을 사용하여 크기 조정 이미지 및 텍스트 예제를 모니터링합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!