Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d5df67f

Browse files
author
Joel Steres
committed
Compensate for positioned HTML element
1 parent 4a1abf3 commit d5df67f

File tree

3 files changed

+119
-27
lines changed

3 files changed

+119
-27
lines changed

‎src/core.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// useful private variables
1111
var $document = $(document),
1212
$window = $(window),
13+
$html = $(document.documentElement),
1314
$body = $('body');
1415

1516
// constants

‎src/utility.js

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ function getViewportCollisions(coords, elementWidth, elementHeight) {
170170
// adjusting viewport even though it might be negative because coords
171171
// comparing with are relative to compensated position
172172
var viewportTop = session.scrollTop - session.positionCompensation.top,
173-
viewportLeft =session.scrollLeft - session.positionCompensation.left,
173+
viewportLeft =session.scrollLeft - session.positionCompensation.left,
174174
viewportBottom = viewportTop + session.windowHeight,
175175
viewportRight = viewportLeft + session.windowWidth,
176176
collisions = Collision.none;
@@ -206,38 +206,51 @@ function countFlags(value) {
206206
}
207207

208208
/**
209-
* Compute compensating position offsets if body element has non-standard position attribute.
209+
* Compute compensating position offsets if body or html element has non-static position attribute.
210210
* @private
211211
* @param {number} windowWidth Window width in pixels.
212212
* @param {number} windowHeight Window height in pixels.
213213
* @return {Offsets} The top, left, right, bottom offset in pixels
214214
*/
215215
function computePositionCompensation(windowWidth, windowHeight) {
216-
var bodyWidthWithMargin,
217-
bodyHeightWithMargin,
218-
offsets,
219-
bodyPositionPx;
220-
221-
switch ($body.css('position')) {
222-
case 'absolute':
223-
case 'fixed':
224-
case 'relative':
225-
// jquery offset and position functions return top and left
226-
// offset function computes position + margin
227-
offsets = $body.offset();
228-
bodyPositionPx = $body.position();
229-
// because element might be positioned compute right margin using the different between
230-
// outerWidth computations and add position offset
231-
bodyWidthWithMargin = $body.outerWidth(true);
232-
bodyHeightWithMargin = $body.outerHeight(true);
233-
// right offset = right margin + body right position
234-
offsets.right = (bodyWidthWithMargin - $body.outerWidth() - (offsets.left - bodyPositionPx.left)) + (windowWidth - bodyWidthWithMargin - bodyPositionPx.left);
235-
// bottom offset = bottom margin + body bottom position
236-
offsets.bottom = (bodyHeightWithMargin - $body.outerHeight() - offsets.top) + (windowHeight - bodyHeightWithMargin - bodyPositionPx.top);
237-
break;
238-
default:
239-
// even though body may have offset, no compensation is required
240-
offsets = { top: 0, bottom: 0, left: 0, right: 0 };
216+
// Check if the element is "positioned". A "positioned" element has a CSS
217+
// position value other than static. Whether the element is positioned is
218+
// relevant because absolutely positioned elements are positioned relative
219+
// to the first positioned ancestor rather than relative to the doc origin.
220+
var isPositioned = function(el) {
221+
return el.css('position') !== 'static';
222+
};
223+
224+
var getElementOffsets = function(el) {
225+
var elWidthWithMargin,
226+
elHeightWithMargin,
227+
elPositionPx,
228+
offsets;
229+
// jquery offset and position functions return top and left
230+
// offset function computes position + margin
231+
offsets = el.offset();
232+
elPositionPx = el.position();
233+
234+
// Compute the far margins based off the outerWidth values.
235+
elWidthWithMargin = el.outerWidth(true);
236+
elHeightWithMargin = el.outerHeight(true);
237+
238+
// right offset = right margin + body right position
239+
offsets.right = (elWidthWithMargin - el.outerWidth() - (offsets.left - elPositionPx.left)) + (windowWidth - elWidthWithMargin - elPositionPx.left);
240+
// bottom offset = bottom margin + body bottom position
241+
offsets.bottom = (elHeightWithMargin - el.outerHeight() - offsets.top) + (windowHeight - elHeightWithMargin - elPositionPx.top);
242+
return offsets;
243+
};
244+
245+
var offsets;
246+
247+
if (isPositioned($body)) {
248+
offsets = getElementOffsets($body);
249+
} else if (isPositioned($html)) {
250+
offsets = getElementOffsets($html);
251+
} else {
252+
// even though body may have offset, no compensation is required
253+
offsets = { top: 0, bottom: 0, left: 0, right: 0 };
241254
}
242255

243256
return offsets;

‎test/htmloffset-rel.html

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<!DOCTYPE html>
2+
<html lang="en-US" style="position:relative">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>PowerTip Test Suite</title>
6+
7+
<!-- Library Resources -->
8+
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
9+
10+
<!-- PowerTip Core Resources -->
11+
<script type="text/javascript" src="../src/core.js"></script>
12+
<script type="text/javascript" src="../src/csscoordinates.js"></script>
13+
<script type="text/javascript" src="../src/displaycontroller.js"></script>
14+
<script type="text/javascript" src="../src/placementcalculator.js"></script>
15+
<script type="text/javascript" src="../src/tooltipcontroller.js"></script>
16+
<script type="text/javascript" src="../src/utility.js"></script>
17+
<link rel="stylesheet" type="text/css" href="../css/jquery.powertip.css" />
18+
19+
<!-- Unit Test Scripts -->
20+
<script type="text/javascript" src="tests-bodyoffset.js"></script>
21+
22+
<!-- Custom Styles For Test Cases -->
23+
<style type="text/css">
24+
header, section { margin-bottom: 20px; }
25+
section { border: 1px solid #CCC; margin: 20px; padding: 20px; }
26+
#powerTip { white-space: normal; }
27+
#huge-text div, #huge-text-smart div { text-align: center; }
28+
#huge-text input, #huge-text-smart input { margin: 10px; padding: 10px; }
29+
#huge-text .east, #huge-text-smart .east { margin-left: 450px; }
30+
#session { position: fixed; right: 10px; top: 10px; font-size: 10px; width: 160px; background-color: #fff; border: 1px solid #ccc; padding: 10px; overflow: hidden; }
31+
#session pre { margin: 0; }
32+
</style>
33+
</head>
34+
<body>
35+
<section id="huge-text">
36+
<h2>Huge Text</h2>
37+
<p>The tooltips for the buttons below have a lot of text. The tooltip div is completely elastic for this demo. The tooltips should be properly placed when they render.</p>
38+
<div>
39+
<input type="button" class="north-west-alt" value="North West Alt" />
40+
<input type="button" class="north-west" value="North West" />
41+
<input type="button" class="north" value="North" />
42+
<input type="button" class="north-east" value="North East" />
43+
<input type="button" class="north-east-alt" value="North East Alt" /><br />
44+
<input type="button" class="west" value="West" />
45+
<input type="button" class="east" value="East" /><br />
46+
<input type="button" class="south-west-alt" value="South West Alt" />
47+
<input type="button" class="south-west" value="South West" />
48+
<input type="button" class="south" value="South" />
49+
<input type="button" class="south-east" value="South East" />
50+
<input type="button" class="south-east-alt" value="South East Alt" />
51+
</div>
52+
</section>
53+
<section id="huge-text-smart">
54+
<h2>Huge Text with Smart Placement</h2>
55+
<p>The tooltips for the buttons below have a lot of text. The tooltip div is completely elastic for this demo. The tooltips should be properly placed when they render.</p>
56+
<div>
57+
<input type="button" class="north-west-alt" value="North West Alt" />
58+
<input type="button" class="north-west" value="North West" />
59+
<input type="button" class="north" value="North" />
60+
<input type="button" class="north-east" value="North East" />
61+
<input type="button" class="north-east-alt" value="North East Alt" /><br />
62+
<input type="button" class="west" value="West" />
63+
<input type="button" class="east" value="East" /><br />
64+
<input type="button" class="south-west-alt" value="South West Alt" />
65+
<input type="button" class="south-west" value="South West" />
66+
<input type="button" class="south" value="South" />
67+
<input type="button" class="south-east" value="South East" />
68+
<input type="button" class="south-east-alt" value="South East Alt" />
69+
</div>
70+
</section>
71+
<section id="trapped-mousefollow" data-powertip="This is the tooltip text.&lt;br /&gt;It is tall so you can test the padding.">
72+
<h2>Trapped mouse following tooltip</h2>
73+
<p>This box has a mouse following tooltip.</p>
74+
<p>Trap it in the bottom right corner of the viewport. It should flip out of the way. It should not flip if it only hits one edge.</p>
75+
</section>
76+
<div id="session"><pre /></div>
77+
</body>
78+
</html>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /