jquery를 사용하여 뷰포트를 기준으로 요소의 위치 가져오기
문서가 아닌 뷰포트를 기준으로 페이지에서 요소의 위치를 가져오는 올바른 방법은 무엇입니까?jQuery.offset
기능이 유망해 보였습니다.
첫 번째 요소의 현재 좌표를 가져오거나 일치하는 요소 집합에서 문서를 기준으로 모든 요소의 좌표를 설정합니다.
하지만 그것은 문서와 관련이 있습니다.뷰포트를 기준으로 오프셋을 반환하는 동등한 방법이 있습니까?
요소의 크기와 위치를 결정하는 가장 쉬운 방법은 getBoundingClientRect() 메서드를 호출하는 것입니다.이 메서드는 뷰포트 좌표의 요소 위치를 반환합니다.인수가 필요하지 않으며 왼쪽, 오른쪽, 위쪽 및 아래쪽 속성을 가진 개체를 반환합니다.왼쪽 및 위쪽 특성은 요소의 왼쪽 상단 모서리의 X 및 Y 좌표를 나타내고 오른쪽 및 아래쪽 특성은 오른쪽 하단 모서리의 좌표를 나타냅니다.
element.getBoundingClientRect(); // Get position in viewport coordinates
모든 곳에서 지원됩니다.
다음은 (확대된) 치수 플러그인을 사용하지 않고 페이지 높이와 스크롤 양(x,y)을 가져오는 두 가지 기능입니다.
// getPageScroll() by quirksmode.com
function getPageScroll() {
var xScroll, yScroll;
if (self.pageYOffset) {
yScroll = self.pageYOffset;
xScroll = self.pageXOffset;
} else if (document.documentElement && document.documentElement.scrollTop) {
yScroll = document.documentElement.scrollTop;
xScroll = document.documentElement.scrollLeft;
} else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
xScroll = document.body.scrollLeft;
}
return new Array(xScroll,yScroll)
}
// Adapted from getPageSize() by quirksmode.com
function getPageHeight() {
var windowHeight
if (self.innerHeight) { // all except Explorer
windowHeight = self.innerHeight;
} else if (document.documentElement && document.documentElement.clientHeight) {
windowHeight = document.documentElement.clientHeight;
} else if (document.body) { // other Explorers
windowHeight = document.body.clientHeight;
}
return windowHeight
}
jQuery.offset
이 다이어그램에 표시된 것처럼 및 와 결합해야 합니다.
데모:
function getViewportOffset($e) {
var $window = $(window),
scrollLeft = $window.scrollLeft(),
scrollTop = $window.scrollTop(),
offset = $e.offset(),
rect1 = { x1: scrollLeft, y1: scrollTop, x2: scrollLeft + $window.width(), y2: scrollTop + $window.height() },
rect2 = { x1: offset.left, y1: offset.top, x2: offset.left + $e.width(), y2: offset.top + $e.height() };
return {
left: offset.left - scrollLeft,
top: offset.top - scrollTop,
insideViewport: rect1.x1 < rect2.x2 && rect1.x2 > rect2.x1 && rect1.y1 < rect2.y2 && rect1.y2 > rect2.y1
};
}
$(window).on("load scroll resize", function() {
var viewportOffset = getViewportOffset($("#element"));
$("#log").text("left: " + viewportOffset.left + ", top: " + viewportOffset.top + ", insideViewport: " + viewportOffset.insideViewport);
});
body { margin: 0; padding: 0; width: 1600px; height: 2048px; background-color: #CCCCCC; }
#element { width: 384px; height: 384px; margin-top: 1088px; margin-left: 768px; background-color: #99CCFF; }
#log { position: fixed; left: 0; top: 0; font: medium monospace; background-color: #EEE8AA; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!-- scroll right and bottom to locate the blue square -->
<div id="element"></div>
<div id="log"></div>
특히 Dimensions 플러그인을 조사합니다.scrollTop()
/scrollLeft()
정보는 http://api.jquery.com/scrollTop 에서 확인할 수 있습니다.
뷰포트 내 요소의 현재 위치를 계산하는 함수는 다음과 같습니다.
/**
* Calculates the position of a given element within the viewport
*
* @param {string} obj jQuery object of the dom element to be monitored
* @return {array} An array containing both X and Y positions as a number
* ranging from 0 (under/right of viewport) to 1 (above/left of viewport)
*/
function visibility(obj) {
var winw = jQuery(window).width(), winh = jQuery(window).height(),
elw = obj.width(), elh = obj.height(),
o = obj[0].getBoundingClientRect(),
x1 = o.left - winw, x2 = o.left + elw,
y1 = o.top - winh, y2 = o.top + elh;
return [
Math.max(0, Math.min((0 - x1) / (x2 - x1), 1)),
Math.max(0, Math.min((0 - y1) / (y2 - y1), 1))
];
}
반환 값은 다음과 같이 계산됩니다.
용도:
visibility($('#example')); // returns [0.3742887830933581, 0.6103752759381899]
데모:
function visibility(obj) {var winw = jQuery(window).width(),winh = jQuery(window).height(),elw = obj.width(),
elh = obj.height(), o = obj[0].getBoundingClientRect(),x1 = o.left - winw, x2 = o.left + elw, y1 = o.top - winh, y2 = o.top + elh; return [Math.max(0, Math.min((0 - x1) / (x2 - x1), 1)),Math.max(0, Math.min((0 - y1) / (y2 - y1), 1))];
}
setInterval(function() {
res = visibility($('#block'));
$('#x').text(Math.round(res[0] * 100) + '%');
$('#y').text(Math.round(res[1] * 100) + '%');
}, 100);
#block { width: 100px; height: 100px; border: 1px solid red; background: yellow; top: 50%; left: 50%; position: relative;
} #container { background: #EFF0F1; height: 950px; width: 1800px; margin-top: -40%; margin-left: -40%; overflow: scroll; position: relative;
} #res { position: fixed; top: 0; z-index: 2; font-family: Verdana; background: #c0c0c0; line-height: .1em; padding: 0 .5em; font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="res">
<p>X: <span id="x"></span></p>
<p>Y: <span id="y"></span></p>
</div>
<div id="container"><div id="block"></div></div>
2014년 1월 현재 cballou의 답변이 Firefox에서 더 이상 작동하지 않는다는 것을 알게 되었습니다.구체적으로.if (self.pageYOffset)
클라이언트가 제대로 스크롤했다면 트리거하지 않았지만, 아래로 스크롤하지 않았기 때문입니다.0
잘못된 숫자입니다.파이어폭스가 지원했기 때문에 한동안 감지되지 않았습니다.document.body.scrollLeft
/Top
하지만 Firefox 26.0에서는 더 이상 작동하지 않습니다.
수정된 솔루션은 다음과 같습니다.
var getPageScroll = function(document_el, window_el) {
var xScroll = 0, yScroll = 0;
if (window_el.pageYOffset !== undefined) {
yScroll = window_el.pageYOffset;
xScroll = window_el.pageXOffset;
} else if (document_el.documentElement !== undefined && document_el.documentElement.scrollTop) {
yScroll = document_el.documentElement.scrollTop;
xScroll = document_el.documentElement.scrollLeft;
} else if (document_el.body !== undefined) {// all other Explorers
yScroll = document_el.body.scrollTop;
xScroll = document_el.body.scrollLeft;
}
return [xScroll,yScroll];
};
FF26, Chrome 31, IE11에서 테스트 및 작동.거의 확실하게 이전 버전의 모든 것에서 작동합니다.
언급URL : https://stackoverflow.com/questions/1567327/using-jquery-to-get-elements-position-relative-to-viewport
'programing' 카테고리의 다른 글
빈 이름을 참조하여 @Scheduled 주석에서 @ConfigurationProperties 사용 (0) | 2023.08.21 |
---|---|
"return false;"는 무엇을 합니까? (0) | 2023.08.21 |
선택 요소에서 선택한 옵션 가져오기 (0) | 2023.08.21 |
null을 삽입할 때 기본값 삽입 (0) | 2023.08.21 |
출력 파일 이름, select-string이 있는 문자열이 아님 (0) | 2023.08.21 |