The family of offset

Offset dimensions are an important concept in javascript. OffsetLeft, offsetTop, offsetHeight and offsetWidth are the main attributes involved in offsets. Of course, there is also an offset reference – the location parent offsetParent. This article covers this section in detail

Locate the parent

Before you can understand the offset size, you need to understand offsetParent. People don’t translate offsetParent as offsetParent, they translate it as location parent, in large part because offsetParent is related to location

OffsetParent is defined as the parent of an element that has been recently positioned (position is not equal to static) with the current element

  1. The element itself has fixed positioning, and the result of offsetParent is null

    When the element itself has fixed positioning, we know that the element with fixed positioning is positioned relative to the viewport. In this case, there is no positioning parent, and the result of offsetParent is null

    [Caution] The Firefox browser has compatibility problems

<div id="test" style="position:fixed"></div>    
<script>
   var test = document.getElementById('test');
   // Firefox does not consider the fixed location issue and returns . All other browsers return null
   console.log(test.offsetParent);
</script>
Copy the code
  1. The element itself has no fixed position, and neither parent has a position set. The result of offsetParent is body
<div id="test"></div>    
<script>
    var test = document.getElementById('test');
    console.log(test.offsetParent);//<body>
</script>
Copy the code
  1. The element itself has no fixed positioning, and the parent element has a positioned element. The result of offsetParent is the closest positioned parent element to the element itself
<div id="grandfather" style="position: relative;">
    <div id="father" >
        <div id="test"></div>
    </div>
</div>
<script type="text/javascript">
    var test = document.getElementById('test');
    // The nearest parent to which the child element has been located. If the parent does not exist, offsetParent is the :body element;
    console.log(test.offsetParent);
</script>
Copy the code
  1. <body>The offsetParent of the element is null
console.log(document.body.offsetParent);//null
Copy the code

The offset

Offset includes four attributes offsetHeight, offsetWidth, offsetLeft and offsetTop

offsetWidth

OffsetWidth indicates the horizontal space occupied by an element, in no units (in pixels px)

offsetWidth =  border-left-width + padding-left + width + padding-right + border-right-width; 
Copy the code
offsetHeight

OffsetHeight indicates the space occupied by an element in the vertical direction, in no units (in pixels px).

offsetHeight =  border-top-width + padding-top + height + padding-bottom + border-bottom-width
Copy the code

Testing:

<! DOCTYPEhtml>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Title</title>
		<style>
			#box {
				width: 200px;
				height: 150px;
				background-color: red;
				padding: 10px;
				border: 5px solid #ddd;
				margin: 10px;
			}
		</style>
	</head>
	<body>
		<div id="box" style="width: 100px; height: 100px;"></div>
		<script>
			var box = document.getElementById('box');
			//offsetHeight = Content height + top and bottom margins + border
			console.log(box.offsetWidth,box.offsetHeight);
			console.log(box.style.width, box.style.height);
			// You can set the size
			// box.style.width = 500 + 'px';
			// You cannot set the size
			box.offsetWidth = 100 + 'px';
		</script>

	</body>
</html>

Copy the code

Note: If you want to change the box size, use xxx.style.width. OffsetWidth and offsetHeight are read-only attributes

offsetTop

OffsetTop represents the pixel distance between the upper and outer border of the element and the upper and inner border of the offsetParent element

offsetLeft

OffsetLeft represents the pixel distance between the left outer border of the element and the left inner border of the offsetParent element

Testing:

<! DOCTYPEhtml>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">* {padding: 0;
				margin: 0;
			}
			#father{
				width: 400px;
				height: 400px;
				background-color: red;
				/* position: relative; * /
				margin: 40px;
			}
			#son {
				width: 200px;
				height: 100px;
				background-color: green;
				padding: 10px;
				border: 5px solid #DA70D6;
				margin-left: 20px;
			}
		</style>
	</head>
	<body>
		<div id="father">
			<div id="son"></div>
		</div>
		<script type="text/javascript">
			var box = document.getElementById('son');
            // If there is a parent location element
			console.log(box.offsetLeft);/ / 20
			console.log(box.offsetTop); / / 0
			// If there is no parent to locate the element
			console.log(box.offsetLeft);/ / 60
			console.log(box.offsetTop); / / 40
		</script>
	</body>
</html>

Copy the code

Summary: The left and top margins relative to the parent (see if the parent has a position, if so, based on the parent, if not, and if not, based on the body)

Finds the page offset for the current element

To know the offset of an element on the page, add the element’s offsetLeft and offsetTop to the same attribute of its offsetParent, add the border in the corresponding direction of the offsetParent, and loop all the way to the root element to get the offset from the element to the page

<div style="padding: 20px; border:1px solid black; position:absolute;">
    <div id="test" style="width:100px; height:100px; margin:10px; background-color: red;"></div>
</div>
<script type="text/javascript">
    var test = document.getElementById('test');
    console.log(getElementLeft(test)); //39px
    console.log(getElementTop(test)); // 39px

    function getElementLeft(ele){
        var actualLeft  = ele.offsetLeft;
        var parent = ele.offsetParent;
        while(parent ! =null){
            actualLeft = actualLeft + parent.offsetLeft + parent.clientLeft;
            parent = parent.offsetParent;
        }
        return actualLeft + 'px';
    }
    function getElementTop(ele){
        var actualTop  = ele.offsetTop;
        var parent = ele.offsetParent;
        while(parent ! =null){
            actualTop = actualTop + parent.offsetTop + parent.clientTop;
            parent = parent.offsetParent;
        }
        return actualTop + 'px';
    }
</script>
Copy the code

The family of the client

In general, there is the offset size, the client size and the scroll size. The offset property has been introduced before, and the scroll size will be introduced later. This article mainly introduces the client area size.

Customer area size

Client area size A client is the amount of space occupied by the content of an element and its inner margins

clientHeight

The clientHeight attribute returns the height of the element node’s client area

clientHeight = padding-top + height + padding-bottom
Copy the code

clientWidth

The clientWidth attribute returns the client area width of the element node

clientWidth = padding-left + width + padding-right
Copy the code

clientLeft

The clientLeft property returns the width of the left borderCopy the code

clientTop

The clientTop property returns the width of the upper borderCopy the code

validation

<div id="box" style="width: 200px; height: 200px; background-color: red; padding: 20px; border: 1px solid orange;"></div>
<script type="text/javascript">
    var box = document.getElementById('box');
    console.log(box.clientWidth);200+ 20+ 20 = 240
    console.log(box.clientHeight); 200 + 20 + 20 = 240
    console.log(box.clientLeft);/ / 1
    console.log(box.clientTop);/ / 1
</script>
Copy the code

The page size

The client property of document.documentElement is used to represent the page size (excluding the scrollbar width)

document.documentElement.clientWidth;
document.documentElement.clientHeight;
Copy the code

Pay attention to

1. All client properties are read-only

<div id="test" style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px solid black;"></div>
<script>
    var test = document.getElementById('test');
    console.log(test.clientHeight);
    // Static failed
    test.clientHeight = 10;
    console.log(test.clientHeight);
</script>
Copy the code

2. If the element is set to display: None, the client property of the client area is 0

<div id="test" style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px solid black; display:none;"></div>
<script>
    var test = document.getElementById('test');
    console.log(test.clientHeight);/ / 0
    console.log(test.clientTop);/ / 0
</script>
Copy the code

3. Client attributes need to be recalculated each time you access the client area. Repeated access consumes a lot of performance. If repeated access is required, their values are stored in variables to improve performance

<div id="test" style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px solid black;"></div>      
<script>
    var test = document.getElementById('test');
    console.time("time");
    for(var i = 0; i < 100000; i++){
        var a = test.clientHeight;
    }
    console.timeEnd('time');/ / 66.798 ms
</script>
Copy the code
<div id="test" style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px solid black;" ></div> <script> var test = document.getElementById('test'); console.time("time"); var a = test.clientHeight; for(var i = 0; i < 100000; i++){ var b = a; } console.timeEnd('time'); / / 1.705 ms < / script >Copy the code

Scroll family

Rolling wide high

scrollHeight

ScrollHeight indicates the total height of an element, including the invisible parts that cannot be displayed on the web page due to overflow

scrollWidth

ScrollWidth represents the total width of an element, including the invisible parts that cannot be displayed on the web page due to overflow

  1. When there is no scrollbar, scrollHeight is equal to the clientHeight property and scrollWidth is equal to the clientWidth property

    <div id="test" style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px solid black;"></div>
    <script>
        var test = document.getElementById('test');
        / / 120 120
        console.log(test.scrollHeight,test.scrollWidth);
        / / 120 120
        console.log(test.clientHeight,test.clientWidth);
    </script>
    Copy the code
  2. When there is a scroll bar but the element width is greater than the element content width and height, the scroll and client properties are the same

    <div id="test" style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px solid black;"></div>
    <script>
        var test = document.getElementById('test');
        / / 120 120
        console.log(test.scrollHeight,test.scrollWidth);
        / / 120 120
        console.log(test.clientHeight,test.clientWidth);
    </script>
    Copy the code

Rolling length

scrollTop

The scrollTop property represents the number of pixels that are hidden above the content area. ScrollTop has a value of 0 when the element is not scrollable, and a value greater than 0 if the element is scrollable vertically, indicating the pixel height of the invisible content above the element

scrollLeft

The scrollLeft property represents the number of pixels hidden to the left of the content area. ScrollLeft has a value of 0 when the element is not scrollLeft, and greater than 0 if the element is scrollLeft horizontally and represents the pixel width of the invisible content to the left of the element

When the scroll bar rolls to the bottom of the content, the following equation is met

scrollHeight = scrollTop + clientHight
Copy the code

Unlike the scrollHeight and scrollWidth properties, scrollLeft and scrollTop are writable

<div id="test" style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px solid black; overflow:scroll; font-size:20px; line-height:200px;">content<br>content<br>
</div>
<button id="btn1">Scroll down</button>
<button id="btn2">Scroll up</button>
<script type="text/javascript">
    // scrollLeft and scrollTop are read and write
    var btn1 = document.getElementById('btn1');
    var btn2 = document.getElementById('btn2');
    btn1.onclick =  function (){
        test.scrollTop += 10;
    }
    btn2.onclick =  function (){
        test.scrollTop -= 10;
    }
</script>
Copy the code

Page scrolling

In theory, most of the browser through the document. The documentElement. ScrollTop and scrollLeft can reflect and control the rolling of the page; The Safari browser is controlled by document.body.scrollTop and scrollLeft


<body style="height: 2000px; width: 2000px;">
    <div id="test" style="width: 100px; height: 100px; padding: 10px; margin: 10px; border: 1px solid black; overflow:scroll; font-size:20px; line-height:200px;">content<br>content<br>
    </div>
    <script type="text/javascript">

        // Page scroll
        window.onscroll = function (){
            console.log(document.documentElement.scrollTop,document.documentElement.scrollLeft);
            console.log(document.body.scrollTop,document.body.scrollLeft);

        }
    </script>
</body>

Copy the code

So, a highly compatible scrolling page is written

var docScrollTop = document.documentElement.scrollTop || document.body.scrollTop
Copy the code
Back to the top
<! DOCTYPEhtml>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body style="height: 2000px;">
        <button id="backTop" style="position: fixed;">Back to the top</button>
        <script type="text/javascript">
            var backTop = document.getElementById('backTop');
            backTop.onclick = scrollTop;
            function scrollTop(){
                // Compatibility
                if(document.documentElement.scrollTop || document.body.scrollTop){
                    document.documentElement.scrollTop = document.body.scrollTop = 0; }}</script>
    </body>
</html>

Copy the code
Rolling method

scrollTo(x,y)

Scroll the current Windows scrollTo (x, y) method, shown in the document, make documents by the specified point coordinates x and y is located in the top left corner of the display area

<body style="height: 2000px;">
    <button id="backTop" style="position: fixed;">Back to the top</button>
    <script src="scrollTop.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        var backTop = document.getElementById('backTop');
        backTop.onclick = scrollTop;
        function scrollTop(){
            scrollTo(0.0);
        }
    </script>
</body>
Copy the code