Coordinates
JavaScript Coordinates (JavaScript坐标)
For moving elements around, it is necessary to learn about coordinates. The majority of JavaScript methods operate with one of the following two coordinate systems: Relative to the window and relative to the document. The first system is like position:fixed and is calculated from the window top/left edge. Its coordinates will be denoted as clientX/clientY.
The second one is similar to position:absolute and is calculated from the document top/left edge. They will be denoted as pageX/pageY.
These coordinates are equal to each other when the page is scrolled to the very beginning, in the way that the window top/left corner is the document top/left corner. Yet, when the document shifts, the elements’ window-relative coordinates change: they move across the window, and the document-relative coordinates stay the same way.
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
<style>
#textId {
height: 950px;
}
div {
border: 1px solid red;
}
h1 {
color: green;
}
h2 {
color: blue;
}
body {
text-align: center;
}
</style>
</head>
<body>
<div id="textId">
<h1>Welcome to w3cdoc</h1>
<h2>MouseEvent clientX and clinetY Property</h2>
<p>To get the x and y of the mouse pointer, click on this page.
</p>
</div>
<p id="divId"></p>
<p id="pageId"></p>
<script>
let elem = document.getElementById('divId');
document.addEventListener('click', function(event) {
elem.innerHTML = "clientX " + event.clientX + ' : ' + " clinetY " + event.clientY;
});
let el = document.getElementById('pageId');
document.addEventListener('click', function(event) {
el.innerHTML = "pageX " + event.pageX + ' : ' + " pageY " + event.pageY;
});
</script>
</body>
</html>
So, for pageY the document-relative coordinate has remained the same, being counted from the top of the document. For clientY the window-relative coordinate has been modified making the arrow shorter. That is because the same point became nearer to the window top. (因此,对于pageY ,文档相对坐标保持不变,从文档顶部开始计数。对于clientY ,窗口相对坐标已被修改,使箭头更短。这是因为同一点变得更接近窗口顶部。)
Element Coordinates: getBoundingClientRect
Element Coordinates: getBoundingClientRect
The elem.getBoundingClientRect() method returns window coordinates for a minimal rectangle enclosing elem like a DOMRect class object. DOMRect has two primary properties: x/y and width/height. The first propertyencompasses X/Y rectangle origin coordinates relative to the window. The second one includes the width and height of the rectangle. It can also be negative.
There are also additional derived properties such as top/bottom and left/right . The first one includes the Y-coordinate for the top/bottom edge of the rectangle. The second one- the X-coordinate for the left/right edge of the rectangle. (还有其他派生属性,如top/bottom和left/right。第一个包括矩形顶部/底部边缘的Y坐标。第二个是矩形左/右边缘的X坐标。)
To see the window coordinates, click the button below:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
<style>
h1 {
color: red;
}
</style>
</head>
<body>
<div id="elem">
<h1>Welcome to w3cdoc</h1>
<p>Move the mouse over the text</p>
<div>
Position:
<p id='text'></p>
</div>
</div>
<script>
let elem = document.getElementById('elem');
document.addEventListener('mousemove', function(event) {
let rect = elem.getBoundingClientRect();
document.getElementById('text').innerHTML = 'left: ' + rect.x + ', ' + 'top: ' + rect.y;
});
</script>
</body>
</html>
While scrolling the page and repeating, it can be noticed that as the window-relative button position changes, its window coordinates are modified in parallel. The picture of elem.getBoundingClientRect() output will look as follows:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
<style>
#elem {
border: 1px solid black;
}
</style>
</head>
<body>
<div id="elem">Welcome to w3cdoc</div>
<script>
let elem = document.getElementById('elem');
alert("top: " + elem.getBoundingClientRect().top +
" bottom: " + elem.getBoundingClientRect().bottom +
" right: " + elem.getBoundingClientRect().right +
" left: " + elem.getBoundingClientRect().left +
" width: " + elem.getBoundingClientRect().width +
" height: " + elem.getBoundingClientRect().height);
</script>
</body>
</html>
Please, take into account that decimal fractions can be used for coordinates. For example, 10.5. There is no necessity to round them while setting to style.left/top. (请注意,小数部分可用于坐标。例如, 10.5。在设置为style.left/top时,无需对其进行四舍五入。)
Also, negative coordinates can be used. For example, if you scroll the page in a way that elem is above the window, then elem.getBoundingClientRect().top will be negative. (此外,还可以使用负坐标。例如,如果以elem位于窗口上方的方式滚动页面,则elem.getBoundingClientRect () .top将为负数。)
There exist some similarities between the window-relative coordinates and CSS position:fixed. But there are differences, too. For example, in CSS positioning, the right property considers the distance from the edge, and the bottom- the distance from the bottom edge. In JavaScript, it is different: all the window coordinates are counted from the top-left corner.
ElementFromPoint(x, y)
ElementFromPoint(x, y) (ElementFromPoint (x, y))
At the window coordinates (x, y), the document.elementFromPoint(x, y) call returns the most nested element. Its syntax looks like this:
let elem = document.elementFromPoint(x, y);
For highlighting and outputting the element tag, which is in the middle of the window, the code below is used:
let centerX = document.documentElement.clientWidth / 2;
let centerY = document.documentElement.clientHeight / 2;
let el = document.elementFromPoint(centerX, centerY);
el.style.background = "green";
console.log(el.tagName);
As window coordinates are used by it, the element can be different depending on the current scroll position. (由于它使用窗口坐标,因此元素可以根据当前滚动位置而不同。)
The document.elementFromPoint(x,y) method operates only when (x,y) are in the visible area. (Document.elementFromPoint (x, y)方法仅在(x, y)位于可见区域时运行。)
In case any coordinate exceeds the window width/height or is negative, null is returned. (如果任何坐标超过窗口宽度/高度或为负数,则返回null。)
A typical error that may occur in case of not checking for it looks as follows:
let el = document.elementFromPoint(x, y);
// if the coordinates are outside the window, then el = null
el.style.background = ''; // Error!
“Fixed” Positioning
“Fixed” Positioning (固定位置)
Mostly, coordinates are- used for positioning something. (大多数情况下,坐标用于定位某物。)
The getBoundingClientRect method can be used for showing something next to an element. It is used for getting its coordinates, and then CSS getBoundingClientRect with right/bottom and left/top is used. (GetBoundingClientRect方法可用于在元素旁边显示内容。它用于获取其坐标,然后使用带有右/底和左/顶的CSS getBoundingClientRect。)
Let’s see an example with the usage of the createTextUnder(element, html) function:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
<style>
h1 {
color: green;
}
</style>
</head>
<body>
<div id="textId">
</div>
<script>
let element = document.getElementById("textId");
function createTextUnder(element, html) {
// create text element
(//create text元素)
let text = document.createElement('div');
// it’s recommended to apply here a css class for the style
(//建议在此处为样式应用css类)
text.style.cssText = "position:fixed; color: green; font-size: 25px";
// assign coordinates, don't forget "px"!
(//分配坐标,别忘了“px” !)
let coords = element.getBoundingClientRect();
text.style.left = coords.left + "px";
text.style.top = coords.bottom + "px";
text.innerHTML = html;
return text;
}
let text = createTextUnder(element, 'Welcome to w3cdoc');
document.body.append(text);
setTimeout(() => text.remove(), 3000);
</script>
</body>
</html>
You can modify the code for showing the message at the right, left, below, applying CSS animation, and more. Having all the coordinates and sizes of the element makes it easily doable. (您可以修改代码,以便在右侧、左侧、下方显示消息、应用CSS动画等。拥有元素的所有坐标和大小使其易于实现。)
But, the message flows away from the button when the page is scrolled. To modify that, it’s necessary to apply document-based coordinates and position:absolute.
Document Coordinates
Document Coordinates (文档坐标)
The document-relative coordinates begin from the upper-left corner rather than the window. (文档相对坐标从左上角开始,而不是从窗口开始。)
In CSS, the window coordinates match position:fixed. On the contrary, the document coordinates are like position:absolute on top.
You can connect two coordinate systems with the following formula:
pageY = clientY plus the height of the document scrolled-out vertical part. (- pageY = clientY加上文档滚出的垂直部分的高度。)
pageX = client plus the width of the document scrolled-out horizontal part. (- pageX = client加上文档滚出的水平部分的宽度。)
The getCoords(elem) function takes the window coordinates from elem.getBoundingClientRect() adding the current scroll to them, like this:
function getCoords(elem) {
let box = elem.getBoundingClientRect();
return {
top: box.top + window.pageYOffset,
left: box.left + window.pageXOffset
};
}
In the example above, it is used with position:absolute . Afterward, the message stays next to the element on the scroll.
The changed createMessageUnder function will look like this:
let element = document.getElementById("textId");
function createTextUnder(element, html) {
let text = document.createElement('div');
text.style.cssText = "position:absolute; color: red";
let coords = getCoords(element);
text.style.left = coords.left + "px";
text.style.top = coords.bottom + "px";
text.innerHTML = html;
return text;
}
Summary
Summary (概要)
In this chapter, we covered the ways of working with coordinates in JavaScript. So, each point on the pages should have coordinates such as relative to the window (elem.getBoundingClientRect()) and relative to the document (elem.getBoundingClientRect()+ the current page scroll). (在本章中,我们介绍了在JavaScript中使用坐标的方法。 因此,页面上的每个点都应具有相对于窗口( elem.getBoundingClientRect ( ) )和相对于文档( elem.getBoundingClientRect ( ) +当前页面滚动)的坐标。)
The window coordinates properly work with position:fixed, and the document coordinates- with position:absolute.
Coordinates can have both advantages and disadvantages, hence at times, you may need to use CSS position absolute and fixed. (坐标既有优点也有缺点,因此有时可能需要使用CSS position absolute和fixed。)