aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html
blob: aa08829542153c6ac852898c4428d338f0fb799e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
---
title: 坐标系
slug: Web/CSS/CSSOM_View/Coordinate_systems
translation_of: Web/CSS/CSSOM_View/Coordinate_systems
original_slug: Web/CSS/CSSOM_View/坐标系
---
<div>{{cssref}}</div>

<p>当我们需要在图形上指定一点的坐标{{interwiki("wikipedia", "algebra")}}),这个坐标需要先对于某一个固定点. 这个固定点我们称为原点{{interwiki("wikipedia", "Origin_(mathematics)", "origin")}}. 这个指定点的坐标即为包含在各个维度上相对于远点的距离值。</p>

<p>下面我将谈谈基于CSS对象模型的坐标系系统。大体上来讲这些坐标系唯一的不同就是坐标原点不一样。</p>

<h2 id="Dimensions坐标维度">Dimensions坐标维度</h2>

<p>在网页技术里,通常来讲,相对于坐标原点,x轴指向右为正值,向左为负值;y轴向下为正值,向上为负值。</p>

<p>On the web, the default origin is the <em>top</em>-left corner of a given context (with positive y-coordinate values being below the origin). Note that this is unlike most mathematical models, where the origin is at the <em>bottom</em>-left corner, with positive y-coordinate values being above the origin.</p>

<p>When drawing 3D graphics, or using a third dimension to layer objects from front to back, the <em>z-coordinate</em> is also used. This specifies the distance away from the viewer if positive and toward the viewer if negative.</p>

<div class="note">
<p>It's actually possible to change the definitions and orientations of these coordinate systems using CSS properties such as {{cssxref("transform")}}. However, we'll only talk about the standard coordinate system for now.</p>
</div>

<h2 id="Standard_CSSOM_coordinate_systems">Standard CSSOM coordinate systems</h2>

<p>There are four standard coordinate systems used by the CSS object model, as described below.</p>

<h3 id="Offset">Offset</h3>

<p>Coordinates specified using the "offset" model use the top-left corner of the element being examined, or on which an event has occurred.</p>

<p>For example, when a {{domxref("MouseEvent", "mouse event", "", 1)}} occurs, the position of the mouse as specified in the event's {{domxref("MouseEvent.offsetX", "offsetX")}} and {{domxref("MouseEvent.offsetY", "offsetY")}} properties are given relative to the top-left corner of the node to which the event has been delivered. The origin is inset by the distances specified by {{cssxref("padding-left")}} and {{cssxref("padding-top")}}.</p>

<h3 id="Client">Client</h3>

<p>The "client" coordinate system uses as its origin the top-left corner of the viewport or browsing context in which the event occurred. This is the entire viewing area in which the document is presented. Scrolling is not a factor.</p>

<p>On a desktop computer, for example, the {{domxref("MouseEvent.clientX")}} and {{domxref("MouseEvent.clientY")}} properties indicate the position of the mouse cursor at the moment the event occurred, relative to the top-left corner of the browser window. The top-left corner of the window is always (0, 0), regardless of the content of the document or any scrolling that may have been done. In other words, scrolling the document will change the client coordinates of a given position within the document.</p>

<h3 id="Page">Page</h3>

<p>The "page" coordinate system gives the position of a pixel relative to the top-left corner of the entire {{domxref("Document")}} in which the pixel is located. That means that a given point in an element within the document will keep the same coordinates in the page model unless the element moves (either directly by changing its position or indirectly by adding or resizing other content).</p>

<p>Mouse events' {{domxref("MouseEvent.pageX", "pageX")}} and {{domxref("MouseEvent.pageY", "pageY")}} properties provide the position of the mouse at the time the event was generated, given relative to the top-left corner of the document.</p>

<h3 id="Screen">Screen</h3>

<p>Finally, we come to the "screen" model. It's probably fairly obvious what this is: it's the coordinate system where the origin is located at the top-left corner of the user's entire screen space. This means that the position of a given point within a document will change if the containing window is moved, for example, or if the user's screen geometry changes (by changing display resolution or by adding or removing monitors to their system).</p>

<p>The {{domxref("MouseEvent.screenX")}} and {{domxref("MouseEvent.screenY")}} properties give the coordinates of a mouse event's position relative to the screen's origin.</p>

<h2 id="Example" name="Example">Example</h2>

<p>Let's take a look at an example. This simple example creates a set of nested boxes. Whenever the mouse enters, moves around inside, or exits the inner box, the corresponding event is handled by updating a set of informational messages within the box, listing out the current mouse coordinates in each of the four available <a href="/en-US/docs/Web/CSS/CSSOM_View/Coordinate_systems">coordinate systems</a>.</p>

<h3 id="JavaScript">JavaScript</h3>

<p>Let's look at the script in two sections. First, the code that logs the coordinates to the screen. This code will be called by the event handler for the various mouse events we watch.</p>

<h4 id="Displaying_the_coordinates">Displaying the coordinates</h4>

<p>As we'll see in the HTML, the inner box (the one we're watching for events on) contains several paragraphs; one for each of the four coordinate systems we'll be reporting on.</p>

<pre class="brush: js">let inner = document.querySelector(".inner");
let log = document.querySelector(".log");

function setCoords(e, type) {
  let idX = type + "X";
  let idY = type + "Y";

  document.getElementById(idX).innerText = e[idX];
  document.getElementById(idY).innerText = e[idY];
}
</pre>

<p>A reference to the {{HTMLElement("div")}} inside the inner box which contains the paragraphs that will show the coordinate information is fetched into <code>log</code>.</p>

<p>The <code>setCoords()</code> function is designed to accept as input a {{domxref("MouseEvent")}} and the name of the origin to use when obtaining the coordinates. The implementation is then quite simple. The variables <code>idX</code> and <code>idY</code> are set to strings with the names of the properties corresponding to the coordinates in the given coordinate system. For example, if the value of <code>type</code> is <code>"page"</code>, then <code>idX</code> is <code>"pageX"</code> and <code>idY</code> is <code>"pageY"</code>.</p>

<h4 id="Handling_the_mouse_events">Handling the mouse events</h4>

<p><code>setCoords()</code> is called by the event handler for the various mouse events, named <code>update()</code>; this is shown below.</p>

<pre class="brush: js">function update(e) {
  setCoords(e, "offset");
  setCoords(e, "client");
  setCoords(e, "page");
  setCoords(e, "screen");
}

inner.addEventListener("mouseenter", update, false);
inner.addEventListener("mousemove", update, false);
inner.addEventListener("mouseleave", update, false);</pre>

<p>The event handler is in the <code>update()</code> method. It simply calls <code>setCoords()</code> once for each coordinate system, passing in the event that occurred.</p>

<p>Our main code sets up the event handlers on the inner box by calling {{domxref("EventTarget.addEventListener", "addEventListener()")}} for each of the types {{event("mouseenter")}}, {{event("mousemove")}}, and {{event("mouseleave")}}.</p>

<h3 id="HTML">HTML</h3>

<p>The HTML for our example is below. Note that within the <code>&lt;div&gt;</code> with the ID <code>"log"</code>, we have a paragraph for each coordinate system, with {{domxref("span")}} used for each of the elements to receive and display the coordinates in each model.</p>

<pre class="brush: html">&lt;div class="outer"&gt;
  &lt;div class="inner"&gt;
    &lt;div class="log"&gt;
      &lt;p&gt;
        Offset-relative: &lt;span id="offsetX"&gt;0&lt;/span&gt;,
        &lt;span id="offsetY"&gt;0&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        Client-relative: &lt;span id="clientX"&gt;0&lt;/span&gt;,
        &lt;span id="clientY"&gt;0&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        Page-relative: &lt;span id="pageX"&gt;0&lt;/span&gt;,
        &lt;span id="pageY"&gt;0&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        Screen-relative: &lt;span id="screenX"&gt;0&lt;/span&gt;,
        &lt;span id="screenY"&gt;0&lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</pre>

<details open><summary>
<h3 id="CSS">CSS</h3>
</summary>

<p>The CSS is pretty much just for appearances here. The class <code>"outer"</code> is used for the containing box, which is intentionally too wide to show in the MDN window, to allow you to scroll it horizontally. The <code>"inner"</code> box is the one that we track events in and in which we show the mouse coordinates.</p>

<pre class="brush: css">.outer {
  width: 1000px;
  height: 200px;
  background-color: red;
}

.inner {
  position: relative;
  width: 500px;
  height: 150px;
  top: 25px;
  left: 100px;
  background-color: blue;
  color: white;
  cursor: crosshair;
  user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
}

.log {
  position: relative;
  width: 100%;
  text-align: center;
}</pre>
</details>

<h3 id="Result">Result</h3>

<p>Here you can see the results in action. As you mouse in and around the blue box, watch the values of the mouse's X and Y coordinates change in the various coordinate systems in which you can obtain the values. Note also the effect of scrolling the example horizontally upon the values returned and how the value of <code>clientX</code> doesn't change.</p>

<p>{{EmbedLiveSample("Example", 600, 250)}}</p>

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="/en-US/docs/Web/CSS/CSS_Transforms/Using_CSS_transforms">Using CSS transforms</a>: how to alter a coordinate system</li>
 <li>Coordinates of a mouse event:
  <ul>
   <li>{{domxref("MouseEvent.offsetX")}} and {{domxref("MouseEvent.offsetY")}}</li>
   <li>{{domxref("MouseEvent.clientX")}} and {{domxref("MouseEvent.clientY")}}</li>
   <li>{{domxref("MouseEvent.pageX")}} and {{domxref("MouseEvent.pageY")}}</li>
   <li>{{domxref("MouseEvent.screenX")}} and {{domxref("MouseEvent.screenY")}}</li>
  </ul>
 </li>
</ul>