Home  >  Article  >  Web Front-end  >  JS uses scroll to monitor resize image and text examples

JS uses scroll to monitor resize image and text examples

零下一度
零下一度Original
2017-06-17 10:34:441176browse

This article mainly introduces you to the relevant information of using scroll to monitor resize in JS. The article introduces it in detail through the example code. It has certain reference and learning value for everyone's study or work. Friends who need it Let’s take a look below.

Preface

Everyone knows that the native resize event can only act on the defaultView, that is, the window, so what method should we use To monitor the size changes of other elements? The author recently discovered a magical method to indirectly implement the monitoring of the resize event through the scroll event. This article will analyze the principle and code implementation of this method.

Principle

First, let’s take a look at what the scroll event does.

The scroll event is fired when the document view or an element has been scrolled.

The scroll event is fired when the document view or an element has been scrolled.

That is to say, this event will be triggered when the element scrolls. So when will the element scroll? An element can be scrolled when it is larger than its parent element and the parent element allows it to scroll. In other words, elements that can be scrolled mean that parent and child elements are not sized the same, which is the core of this approach.

Then we need to make scrollLeft or scrollTop change when the element size changes, thereby triggering the scroll event and further knowing that its size has changed.

Listen for the element to become larger

When the element becomes larger, we can see more, and its internal scrollable area will slowly decrease Small, but this will not cause the position of the scroll bar to change, but when the element is large enough to make the scroll bar disappear, it will cause scrollLeft or scrollTop to become 0, so we know that the element has become larger, so we actually only need 1px To judge, the icon is as follows:

The listening element becomes smaller

When the element When it becomes smaller, the scrollable area will become larger, but the position of the scroll bar will not actually change. The approach taken here is to shrink the scrollable area and the parent element at a certain ratio, and let the parent element squeeze and scroll. area, thereby indirectly changing the size of the scroll bar scrollLeft or scrollTop. The text description may not be very clear. Let’s look at the picture below:

Through the above two methods, we can Get the resize event.

Implementation

First of all, in order not to affect the original element, we should create an element as large as the element to be monitored, and It performs related operations, and then we need two child elements to monitor the two situations of the element becoming larger and the element becoming smaller respectively. Therefore, the following HTML structure is constructed:


<p class="resize-triggers">
 <p class="expand-trigger">
 <p></p>
 </p>
 <p class="contract-trigger"></p>
</p>

Their corresponding CSS is as follows:


##

.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%;
}

where

. The width and height of the expand-triggers child element should remain 1px greater than the parent element, and both triggers should remain in the lower-right corner, so we can implement the following state reset function, And called during initialization and each scroll event:


/**
 * 重置触发器
 * @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 + &#39;px&#39;; // 保持宽度多1px
 expandChild.style.height = expand.offsetHeight + 1 + &#39;px&#39;; // 保持高度多1px
 expand.scrollLeft = expand.scrollWidth; // 滚动到最右
 expand.scrollTop = expand.scrollHeight; // 滚动到最右
};

We can use the following function to detect whether the element size has changed:


/**
 * 检测触发器状态
 * @param element 要检查的元素
 * @returns {boolean} 是否改变了大小
 */
const checkTriggers = function(element) {
 // 宽度或高度不一致就返回true
 return element.offsetWidth !== element.resizeLast.width || element.offsetHeight !== element.resizeLast.height;
};

Finally, we can add a simple event listener:

##

/**
 * 添加大小更改监听
 * @param element 要监听的元素
 * @param fn 回调函数
 */
export const addResizeListener = function(element, fn) {
if (isServer) return; // 服务器端直接返回
 if (attachEvent) { // 处理低版本ie
 element.attachEvent(&#39;onresize&#39;, fn);
 } else {
if (!element.resizeTrigger) { // 如果没有触发器
  if (getComputedStyle(element).position === &#39;static&#39;) {
  element.style.position = &#39;relative&#39;; // 将static改为relative
  }
createStyles();
  element.resizeLast = {}; // 初始化触发器最后的状态
  element.resizeListeners = []; // 初始化触发器的监听器

  const resizeTrigger = element.resizeTrigger = document.createElement(&#39;p&#39;); // 创建触发器
  resizeTrigger.className = &#39;resize-triggers&#39;;
  resizeTrigger.innerHTML = &#39;<p class="expand-trigger"><p></p></p><p class="contract-trigger"></p>&#39;;
  element.appendChild(resizeTrigger); // 添加触发器

  resetTrigger(element); // 重置触发器
  element.addEventListener(&#39;scroll&#39;, 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); // 加入该回调
 }
};

and the following function to

remove the event

listener :

/**
 * 移除大小改变的监听
 * @param element 被监听的元素
 * @param fn 对应的回调函数
 */
export const removeResizeListener = function(element, fn) {
if (attachEvent) { // 处理ie
 element.detachEvent(&#39;onresize&#39;, fn);
 } else {
 element.resizeListeners.splice(element.resizeListeners.indexOf(fn), 1); // 移除对应的回调函数
 if (!element.resizeListeners.length) { // 如果全部时间被移除
  element.removeEventListener(&#39;scroll&#39;, scrollListener); // 移除滚动监听
  element.resizeTrigger = !element.removeChild(element.resizeTrigger); // 移除对应的触发器,但保存下来
 }
 }
};

OthersSome of the content is for optimization and does not affect the basics Functions, such as the distinction between server rendering and client rendering, special processing for IE, and solving bugs on chrome through opacity animation.

The above is the detailed content of JS uses scroll to monitor resize image and text examples. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn