Encapsulation of js common attributes offset/style/client/scroll/mouse events and methods

1. Element offset offset series

1.1 offset overview

offset — Offset, the position (offset), size, etc. of the element can be dynamically obtained by using the related attributes of the offset series.
  • Get the element distance with the position of the positioning parent element;
  • Get the size (width and height) of the element itself.
  • Note: The returned value does not have a unit

Common attributes of offset series:

offset series attributeseffect
element.offsetParentReturn the parent element with positioning as the element, if the parent element is not positioned, then return the body
element.offsetTopReturns the offset of the element relative to the top of the positioned parent element
element.offsetLeftReturns the offset of the element relative to the left border of the positioned parent element
element.offsetWidthReturn itself including padding, border, width of content area, return value without unit.
element.offsetHeightReturn itself including padding, border, height of content area, return value without unit.

1.2 The difference between offset and style

offsetstyle
offset can get the style value in any style sheetstyle can only get the style value in the inline style sheet
The value obtained by the offset series has no unitstyle.width gets a string with units
offsetWidth contains padding+border+widthstyle.width gets the value without padding and border
offsetWidth is a read-only property, can only be obtained but not assignedstyle.width is a readable and writable attribute, which can be obtained or assigned
Therefore, if
you want to get the size and position of the element, it is more appropriate
to use offset; if you want to change the value of the element, you need to change it with style.
  • Get the element distance with the position of the positioning parent element;
  • Get the size (width and height) of the element itself.
Insert picture description here


Case : Get the coordinates of the mouse in the box

Implementation ideas
① Get the coordinates of the mouse on the page ( e.pageX,  e.pageY)
② Get the distance of the box on the page (  box.offsetLeft,  box.offsetTop)
③ The coordinates of the mouse on the page minus the distance of the box on the page to get the coordinates of the mouse in the box
④ Move the mouse , Get the latest coordinates, use the mouse movement event  mousemove.

Implementation code

var box = document.querySelector('.box'); box.addEventListener('mousemove', function(e) {       var x = e.pageX - this.offsetLeft;        var y = e.pageY - this.offsetTop;        this.innerHTML = 'x坐标是' + x + ' y坐标是' + y; })

2. Element visual area client series

client (client), use the relevant attributes of the client series to obtain the relevant information of the visual area of ​​the element. The frame size and element size of the element can be dynamically obtained through the relevant attributes of the client series.
Client series attributesreturn value
element.clientTopReturns the size of the upper border of the element
element.clientLeftReturns the size of the left border of the element
element.clientWidthReturn itself, including the width of padding/content area, without border, return data without unit
element.clientHeightReturn itself, including the height of padding/content area, without border, return data without unit
Insert picture description here

2.1 Execute function immediately

  • The immediate execution function does not need to be called, and can be executed immediately by itself;
  • Main function: create an independent scope, all variables in it are local variables, avoiding naming conflicts
  • Usage of immediate execution function :
  (function () {})()   //或者  (function () {}()) 
<script>    // (function() {})()    (function(a,b) {        console.log(a + b);    })(1, 2)  // 第二个小括号可以看作是调用函数    // (function() {}())    (function(a,b) {        console.log(a + b);    }(2,3))</script>

The following is  Taobao flexible.js  source code analysis

(function flexible (window, document) {  // 获取html的根元素  var docEl = document.documentElement  // dpr 是物理像素比  var dpr = window.devicePixelRatio || 1   // adjust body font size 设置body的字体大小  function setBodyFontSize () {    // 如果页面中有body这个元素,就设置body的字体大小    if (document.body) {      document.body.style.fontSize = (12 * dpr) + 'px'    }    else {      // 如果页面中没有body这个元素,则等着页面的主要DOM元素加载完毕再去设置body的字体大小      document.addEventListener('DOMContentLoaded', setBodyFontSize)    }  }  setBodyFontSize();   // set 1rem = viewWidth / 10  设置html元素的文字大小  function setRemUnit () {    var rem = docEl.clientWidth / 10    docEl.style.fontSize = rem + 'px'  }   setRemUnit()   // reset rem unit on page resize  当页面尺寸大小发生变化的时候,要重新设置下rem的大小  window.addEventListener('resize', setRemUnit)  // pageshow 是重新加载页面触发的事件  window.addEventListener('pageshow', function (e) {    // e.persisted 返回的是true,就是说如果这个页面是从缓存取过来的页面,也需要重新计算一下rem的大小    if (e.persisted) {      setRemUnit()    }  })   // detect 0.5px supports  有些移动端的浏览器不支持0.5像素的写法  if (dpr >= 2) {    var fakeBody = document.createElement('body')    var testElement = document.createElement('div')    testElement.style.border = '.5px solid transparent'    fakeBody.appendChild(testElement)    docEl.appendChild(fakeBody)    if (testElement.offsetHeight === 1) {      docEl.classList.add('hairlines')    }    docEl.removeChild(fakeBody)  }}(window, document))

2.2 Triggering of load event

The following three situations will refresh the page and trigger the load event

Hyperlink of a label
F5 or refresh button (force refresh)
forward and back button
However, there is a feature in Firefox-"round-trip cache", this cache not only saves page data, but also saves the state of DOM and JavaScript; in fact, the entire page is stored in memory. So the back button cannot refresh the page at this time .
—— But you can use  pageshowevents to trigger. This event is triggered when the page is displayed, regardless of whether the page comes from the cache. In the reloading of the page, it pageshowwill be loadtriggered after the event is triggered; according to the event object persistedto determine whether it is an pageshowevent triggered by the page in the cache , pay attention to this event is added to the window.

3. Element scroll scroll series

3.1 Attributes of element scroll series

Scroll means scrolling. The size and scroll distance of the element can be dynamically obtained by using the related attributes of the scroll series.

scroll series propertieseffect
element.scrollTopReturn the upper distance to be rolled, the return value does not carry the unit
element.scrollLeftReturns the distance to the left of being rolled, the return value does not carry a unit
element.scrollWidthReturns the actual width of itself, without borders, returns the value without units
element.scrollHeightReturns the actual height of itself, without borders, returns the value without units
Insert picture description here

3.2 The scrolled head of the page

If the height or width of the browser is not large enough to display the entire page, a scroll bar will appear automatically. When the scroll bar is scrolled down, the height above the page is hidden, we call it the scrolled head of the page. The scroll bar will trigger an onscroll event when it scrolls  .

Case: Taobao fixed the right sidebar

  • The original sidebar is absolutely positioned
  • When the page scrolls to a certain position, the sidebar changes to a fixed position;
  • If the page continues to scroll, the display will return to the top.

Realization ideas

① page scroll event  scroll, Event Source: document;
② Scroll to a location and get the upper value of the page is rolled go;
③ page is rolled to head: by window.pageYOffsetobtaining. (If it is the left side of the scroll, it is obtained through window.pageXOffset);
④ Note: the head of the element is scrolled element.scrollTop ; if it is the head  of the page scrolled, it is  window.pageYOffset;
this value can also be obtained through the box  offsetTop, if ≥This value makes the box a fixed position.

3.3 Header compatibility solution when the page is scrolled

It should be noted that the scrolled header of the page has compatibility issues. Therefore, the scrolled header usually has the following writing methods:

  1. Declared DTD, use document.documentElement.scrollTop
  2. No DTD declared, use document.body.scrollTop
  3. New methods window.pageYOffset and window.pageXOffset, IE9 began to support

Compatibility function package

function getScroll() {  return {    left: window.pageXOffset || document.documentElement.scrollLeft ||document.body.scrollLeft||0,    top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0  };}

Compatibility function call

getScroll().left

Three series summary

Three series size comparisoneffect
element.offsetWidthReturn itself, including padding, border, width of content area, return value without unit
element.clientWidthReturns itself, including padding, the width of the content area, without borders. Return value without unit
element.scrollWidthReturns the actual width of itself, without borders. Return value without unit

Main purpose / usage :

seriesUse, usage
offsetseriesOften used to get element position offsetLeft、offsetTop
clientseriesOften used to get element size clientWidth、 clientHeight
scrollseriesOften used to get the scroll distance scrollTop 、scrollLeft

Note : The page scrolling distance is  window.pageXOffset obtained by

The difference between mouseenter and mouseover

  • mouseenter mouse event
mouseentermouseover
Triggered when the mouse moves over the element 
mouseenterWill only be triggered by its own box ( not bubbling)It will be triggered when the mouse passes over the box itself, and it will also be triggered when it passes through the subbox.
Pair it with it, mouseleave(mouse away) it won’t bubbling either 

4. Animation function package

4.1 Principles of Animation Implementation

Core principle : Keep moving the box position through the timer setInterval().
Implementation steps :

  1. Get the current position of the box
  2. Increase or decrease the moving distance of the box by 1 unit at the current position;
  3. Use the timer to keep repeating this operation
  4. Add a condition to end the timer
Note: This element needs to add positioning before it can be usedelement.style.left

4.2 Simple encapsulation of animation function

The function needs to pass 2 parameters, the animation object and the distance to be moved .

<div></div><span>文化长廊</span><script>        // obj:目标对象 target:目标位置        function animate(obj, target) {            var timer = setInterval(function() {                if (obj.offsetLeft >= target) {                    // 停止动画 其实质是停止定时器。                    clearInterval(timer);                }                obj.style.left = obj.offsetLeft + 1 + 'px';            }, 30);        }        var div = document.querySelector('div');        var span = document.querySelector('span');        // 调用函数        animate(div, 250);        animate(span, 420);</script>

4.3 The animation function records different timers for different elements

If multiple elements use the same animation function, there is no need to declare the timer every time. Different timer
core principles can be used for different elements : Since JavaScript is a dynamic language, it is very convenient to add attributes to the current object.

The example code is as follows:

<button>点我</button>    <div></div>    <span>文化长廊</span>    <script>        // var obj = {};        // obj.name = 'Rose';        // obj:目标对象;target:目标位置        // 给不同的元素指定不同的定时器        function animate(obj, target) {            // 当连续点击按钮,元素的速度会逐渐加快,原因是开启了多个定时器;            // 解决方案:确保只有一个定时器执行;            // 清除先前的定时器,只保留执行当前一个定时器,            clearInterval(obj.timer);            obj.timer = setInterval(function() {                if (obj.offsetLeft >= target) {                    // 停止动画 其实质是停止定时器                    clearInterval(obj.timer);                }                obj.style.left = obj.offsetLeft + 1 + 'px';            }, 30);        }        var div = document.querySelector('div');        var span = document.querySelector('span');        var btn = document.querySelector('button');        // 调用函数        animate(div, 450);        btn.addEventListener('click', function() {            animate(span, 250);        })    </script>

4.4 Principle of easing effect

Easing animation : It is to change the speed of element movement, the most common is to stop the speed slowly to
realize the idea :

  1. Slowly reduce the distance the box moves each time;
  2. Core algorithm:  (target value-current position) / 10  as the distance step for each movement
  3. Conditions for stopping:  Stop the timer when the  current box position = the target position
Note: The step value needs to be rounded.

Example code (ease animation function package):

// 缓动动画函数封装<button>点我</button><span>文化长廊</span>    <script>        // obj:目标对象;target:目标位置        // 1. 让盒子每次移动的距离逐渐变小。        // 2. 每次移动的距离(步长):(目标值 - 现在的位置) / 10         // 3. 停止条件: 当前盒子位置 = 目标位置时        function animate(obj, target) {            // 清除先前的定时器,只保留执行当前一个定时器            clearInterval(obj.timer);            obj.timer = setInterval(function() {                // 步长值写到定时器的里面                var step = (target - obj.offsetLeft) / 10;                if (obj.offsetLeft == target) {                    // 停止动画 其实质是停止定时器                    clearInterval(obj.timer);                }                // 将每次加1这个步长值改为一个慢慢变小的值  步长公式:(目标值 - 当前位置) / 10                obj.style.left = obj.offsetLeft + step + 'px';            }, 15);        }        var span = document.querySelector('span');        var btn = document.querySelector('button');        btn.addEventListener('click', function() {                // 调用函数                animate(span, 500);            })            // 匀速动画 就是 盒子是当前的位置 +  固定的值 10             // 缓动动画就是  盒子当前的位置 + 变化的值(目标值 - 现在的位置) / 10)    </script>

4.5 Animation function moves between multiple target values

You can move the animation function from 800 to 500.
When the button is clicked, judge whether the step size is positive or negative

  1. If it is positive, the step size is rounded up;
  2. If it is negative, the step size is rounded down.

Example code:

// 缓动动画函数封装<button class="btn500">按钮1</button>    <button class="btn800">按钮2</button>    <span>文化长廊</span>    <script>        // obj:目标对象;target:目标位置        // 1. 让盒子每次移动的距离逐渐变小。        // 2. 每次移动的距离(步长):(目标值 - 现在的位置) / 10         // 3. 停止条件: 当前盒子位置 = 目标位置时        function animate(obj, target) {            // 清除先前的定时器,只保留执行当前一个定时器            clearInterval(obj.timer);            obj.timer = setInterval(function() {                // 步长值写到定时器的里面                // 把步长值改为整数 避免出现小数                // var step = Math.ceil((target - obj.offsetLeft) / 10);                var step = (target - obj.offsetLeft) / 10;                step = step > 0 ? Math.ceil(step) : Math.floor(step);                if (obj.offsetLeft == target) {                    // 停止动画 其实质是停止定时器                    clearInterval(obj.timer);                }                // 将每次加1这个步长值改为一个慢慢变小的值  步长公式:(目标值 - 当前位置) / 10                obj.style.left = obj.offsetLeft + step + 'px';            }, 15);        }        var span = document.querySelector('span');        var btn500 = document.querySelector('.btn500');        var btn800 = document.querySelector('.btn800');         btn500.addEventListener('click', function() {            // 调用函数            animate(span, 500);        })        btn800.addEventListener('click', function() {                // 调用函数                animate(span, 800);            })            // 匀速动画 就是 盒子是当前的位置 +  固定的值 10             // 缓动动画就是  盒子当前的位置 + 变化的值(目标值 - 现在的位置) / 10)    </script>

4.6 Add callback function to animation function

The principle of the callback function: a
function can be used as a parameter. Pass this function as a parameter to another function. After that function is executed, the passed function is executed. This process is called callback.
Write the position of the callback function: the position where the timer ends.

4.7 Encapsulate the animation function into a separate JS file

The frequently used animation functions can be individually encapsulated in a JS file, and this JS file can be quoted when using it.

  1. Create a new JS file separately;
  2. HTML file introduces JS file.

5. Common webpage special effects cases

5.1.1 Functional requirements:
1. After the mouse passes the carousel diagram module, the left and right buttons are displayed, and the left and right buttons are hidden when left.
2. Click the right button once, the picture will be played to the left, and so on, the left button is the same.
3. While the picture is playing, the small circle module below changes along with it.
4. Click the small circle to play the corresponding picture.
5. If the mouse does not pass the carousel picture, the carousel picture will automatically play the picture.
6. When the mouse passes over, the carousel diagram module, and the automatic playback stops.

5.1.2 Ideas
① Create a new js folder and js file separately, and import them into the HTML page;
② Add a load event;
③ Move the mouse over the carousel module to display the left and right buttons, and leave to hide the left and right buttons;
④ Show and hide the display button.

5.1.3 The
core idea of dynamically generating small circles :
① The number of small circles should be the same as the number of pictures;
② First get ulthe number of pictures liinside (the pictures are put inside, so it is lithe same number);
③ Use loops to dynamically generate Small circle (this small circle should be put olinside);
④ Create node  var li = createElement('li');
⑤ Insert node  ol. appendChild(li);
⑥ The current class needs to be added to the first small circle.

5.1.4 Set the current small circle (exclusive thought)
① Click the current small circle to add a currentcategory
② The remaining small circles remove a currentcategory

Note: When the small circle is generated, the click event can be directly bound.

5.1.5 Click on the small circle to scroll the picture
① You need to use the animateanimation function, and import the jsfile (Note, because it index.js depends on  animate.js it, animate.js write  index.js it above);
② The premise of using the animation function: the element must be positioned;
③ Pay attention to ul moving instead of small li;
④ rolling core algorithms picture: click on a small circle, pictures scroll. ulMoving distance = index number of the small circle × width of the picture;
⑤ You need to get the index number of the small circle. When generating the small circle, set a custom attribute for it, and click to get the custom attribute.

5.1.6 Click the button on the right to scroll the picture .
① declare variables numper click 1, numincrement ul 滚动距离 = 变量 × 图片宽度1 .

The principle of seamless picture scrolling:  copy the
first licopy of ul and put it ul at the end;
when the picture is scrolled to the last cloned picture, let it ul jump to the far left quickly and without animation: left is 0 ,At the same time num is assigned a value of 0, and the picture will be scrolled from the beginning

② Clone the first picture; clone the ul first one li, cloneNode()

Copy the child nodes inside. cloneNode() Adding true in the brackets is a deep clone and a  false shallow clone.

③ Add to the  ul end  appendChild.

5.1.7 Click the button on the right, and the small circle will follow the change.
① Declare another variable circle. Each time you click it will increment by 1. Because the left and right buttons need this variable, it is declared as a global variable.
② But the number of pictures is one more than the small circle (the first and last pictures are the same), and a judgment condition needs to be added
. ③If there are 5 pictures, there can only be 4 small dots, that is, the judgment is written as  if(circle == 4) and reset to 0.

5.1.8 Auto play function
① Add timer;

Automatically play the carousel, which is actually similar to clicking the button on the right

② At this time, you can manually call the right button click event (such as  right_btn.click()).
③ When the mouse passes over the focus of the carousel, the timer will stop;
④ When the mouse leaves the focus, the timer will start.

5.2 Throttle valve

Prevent the continuous click of the carousel button from causing the playback to be too fast.
The purpose of the throttle : When the content of the previous function animation is executed, the next function animation is executed, so that the event cannot be triggered continuously.
The realization idea : use the callback function, add a variable to control, lock the function and unlock the function.
Start setting a variable  var flag = true;
If(flag) {flag = false; do something} // 关闭水龙头

Use the callback function to complete the animation and  flag = true turn on the faucet.

5.2.1 Case: Back to the top
Scroll the window to a specific position in the document.

window.scroll(x, y)

Note that the xsum inside y does not follow the unit, just write the number directly.

Return to the top with animation
① At this time, you can continue to use the previously encapsulated animation function;
② Just change all the leftrelevant values ​​to be related to the vertical scroll distance of the
page ; ③ How much the page is scrolled can be window.pageYOffset obtained through  ;
④ Finally Is page scrolling, use  window.scroll(x,y).