HTML ๋ฌธ์์์ DOM ์์๊ฐ ํ์ฌ ํ์๋๋์ง ( ๋ทฐํฌํธ ์ ํ์) ์ ์์๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
(์ง๋ฌธ์ Firefox์ ๊ดํ ๊ฒ์ ๋๋ค.)
๋ต๋ณ
์ ๋ฐ์ดํธ : ์๊ฐ์ด ํ๋ฅด๊ณ ๋ธ๋ผ์ฐ์ ๋ ์์ต๋๋ค. ์ด ๊ธฐ์ ์ ๋ ์ด์ ๊ถ์ฅํ์ง ์์ต๋๋ค ๊ทธ๋ฆฌ๊ณ ๋น์ ์ ์ฌ์ฉํด์ผ ๋จ์ ์๋ฃจ์ ์ ์ฌ์ฉํ๋ฉด 7 ์ ์ ์ธํฐ๋ท ์ต์คํ๋ก๋ฌ์ ์ง์ ๋ฒ์ ์ด ํ์ํ์ง ์์ ๊ฒฝ์ฐ.
๋ ์ฐฝ์ ์ธ ์๋ฃจ์ (ํ์ฌ ๊ตฌ์) :
ํ์ฌ ๋ทฐํฌํธ์์ ์์๊ฐ ์์ ํ ๋ณด์ด๋์ง ํ์ธํฉ๋๋ค.
function elementInViewport(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top >= window.pageYOffset &&
left >= window.pageXOffset &&
(top + height) <= (window.pageYOffset + window.innerHeight) &&
(left + width) <= (window.pageXOffset + window.innerWidth)
);
}
๋ทฐํฌํธ์ ์์์ ์ผ๋ถ๊ฐ ๋ณด์ด๋์ง ํ์ธํ๊ธฐ ์ํด ๊ฐ๋จํ ์์ ํ ์ ์์ต๋๋ค.
function elementInViewport2(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}
๋ต๋ณ
์ด์ ๋๋ถ๋ถ์ ๋ธ๋ผ์ฐ์ ๋ getBoundingClientRect ๋ฉ์๋๋ฅผ ์ง์ ํ๋ฉฐ, ์ด๋ ๋ชจ๋ฒ ์ฌ๋ก๊ฐ๋์์ต๋๋ค. ์ค๋๋ ๋๋ต์ ์ฌ์ฉํ์ฌ์ ๋๋ค ๋งค์ฐ ๋๋ฆฌ๊ฒ , ์ ํํ์ง ๋ฐ ์ฌ๋ฌ ๋ฒ๊ทธ๊ฐ ์์ต๋๋ค .
์ฌ๋ฐ๋ฅธ ๊ฒ์ผ๋ก ์ ํํ ์๋ฃจ์ ์ ๊ฑฐ์ ์ ํํ์ง ์์ต๋๋ค . ๋ฒ๊ทธ์ ๋ํ ์์ธํ ๋ด์ฉ์ ์ฝ์ ์ ์์ต๋๋ค .
์ด ์๋ฃจ์ ์ Internet Explorer 7 ์ด์, iOS 5 ์ด์, Safari, Android 2.0 (Eclair) ์ด์, BlackBerry, Opera Mobile ๋ฐ Internet Explorer Mobile 9 ์์ ํ ์คํธ๋์์ต๋๋ค .
function isElementInViewport (el) {
// Special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
);
}
์ฌ์ฉํ๋ ๋ฐฉ๋ฒ:
์์์ ์ฃผ์ด์ง ํจ์๊ฐ ํธ์ถ ๋ ๋ ์ ๋ต์ ๋ฐํํ๋์ง ํ์ธํ ์ ์์ง๋ง ์ด๋ฒคํธ๋ก์ ์์์ ๊ฐ์์ฑ์ ์ถ์ ํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
<body>ํ๊ทธ ํ๋จ์ ๋ค์ ์ฝ๋๋ฅผ ๋ฐฐ์นํ์ญ์์ค .
function onVisibilityChange(el, callback) {
var old_visible;
return function () {
var visible = isElementInViewport(el);
if (visible != old_visible) {
old_visible = visible;
if (typeof callback == 'function') {
callback();
}
}
}
}
var handler = onVisibilityChange(el, function() {
/* Your code go here */
});
// jQuery
$(window).on('DOMContentLoaded load resize scroll', handler);
/* // Non-jQuery
if (window.addEventListener) {
addEventListener('DOMContentLoaded', handler, false);
addEventListener('load', handler, false);
addEventListener('scroll', handler, false);
addEventListener('resize', handler, false);
} else if (window.attachEvent) {
attachEvent('onDOMContentLoaded', handler); // Internet Explorer 9+ :(
attachEvent('onload', handler);
attachEvent('onscroll', handler);
attachEvent('onresize', handler);
}
*/
DOM ์์ ์ ์ํํ๋ฉด ์์์ ๊ฐ์์ฑ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ง์นจ ๋ฐ ์ผ๋ฐ์ ์ธ ํจ์ :
์๋ง ๋น์ ์ ํ์ด์ง ํ๋ / ๋ชจ๋ฐ์ผ ์ฅ์น ํ์น๋ฅผ ์ถ์ ํด์ผํฉ๋๊น? jQuery๋ ์ค / ํ์น ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฒซ ๋ฒ์งธ ๋๋ ๋ ๋ฒ์งธ ๋งํฌ๊ฐ ๋์์ด๋ฉ๋๋ค.
DOM ์ ์์ ํ๋ฉด ์์์ ๊ฐ์์ฑ์ ์ํฅ์ ์ค ์ ์์ต๋๋ค. ์ด๋ฅผ ์ ์ดํ๊ณ handler()์๋์ผ๋ก ํธ์ถ ํด์ผํฉ๋๋ค. ๋ถํํ๋, ์ฐ๋ฆฌ๋ ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ onrepaint์ด๋ฒคํธ ๊ฐ ์์ต๋๋ค . ๋ฐ๋ฉด์ ์์์ ๊ฐ์์ฑ์ ๋ณ๊ฒฝํ ์์๋ DOM ์์ ์ ๋ํด์๋ง ์ต์ ํํ๊ณ ์ฌํ์ธ์ ์ํ ํ ์ ์์ต๋๋ค.
์ด ์์ ์์ CSS๊ฐ ์ ์ฉ๋์๋ค๋ ๋ณด์ฅ์ด ์์ผ๋ฏ๋ก jQuery $ (document) .ready () ์์๋ง ์ฌ์ฉ ํ์ง ๋ง์ญ์์ค . ์ฝ๋๋ ํ๋ ๋๋ผ์ด๋ธ์์ CSS์ ๋ก์ปฌ๋ก ์๋ ํ ์ ์์ง๋ง ์ผ๋จ ์๊ฒฉ ์๋ฒ์ ๋ฃ์ผ๋ฉด ์คํจํฉ๋๋ค.
ํ์ DOMContentLoaded๋ ์คํ์ผ์ด ์ ์ฉ ๋์ง๋ง ์ด๋ฏธ์ง๋ ์์ง๋ก๋๋์ง ์์ต๋๋ค . ๋ฐ๋ผ์ window.onload์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ถ๊ฐํด์ผํฉ๋๋ค .
์์ง ์ค / ํ์น ์ด๋ฒคํธ๋ฅผ ์ก์ ์ ์์ต๋๋ค.
๋ง์ง๋ง ์๋จ์ ๋ค์ ์ฝ๋ ์ผ ์ ์์ต๋๋ค.
/* TODO: this looks like a very bad code */
setInterval(handler, 600);
์น ํ์ด์ง๊ฐ์๋ ํญ์ด ํ์ฑํ๋์ด ์๊ณ ๊ฐ์์ ์ธ์ง ์ ๊ฒฝ ์ฐ๋ฉด HTML5 API ์ ๋ฉ์ง ๊ธฐ๋ฅ pageVisibiliy ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
TODO :์ด ๋ฐฉ๋ฒ์ ๋ ๊ฐ์ง ์ํฉ์ ์ฒ๋ฆฌํ์ง ์์ต๋๋ค.
- ์ฌ์ฉํ์ฌ ๊ฒน์นจ
z-index overflow-scroll์์์ ์ปจํ ์ด๋์์ ์ฌ์ฉ- ์๋ก์ด ๊ฒ์ ์๋ํ์ญ์์ค- ๊ต์ฐจ ๊ด์ฐฐ์ API ์ค๋ช
๋ต๋ณ
์ต์ ์ ๋ณด
์ต์ ๋ธ๋ผ์ฐ์ ์์๋ ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ ์ ๊ณตํ๋ Intersection Observer API ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค .
- ์คํฌ๋กค ์ด๋ฒคํธ๋ฅผ ๋ฃ๋ ๊ฒ๋ณด๋ค ๋์ ์ฑ๋ฅ
- ๊ต์ฐจ ๋๋ฉ์ธ iframe์์ ์๋
- ์์๊ฐ ๋ค๋ฅธ ์์๋ฅผ ๋ฐฉํดํ๊ฑฐ๋ ๊ต์ฐจํ๋์ง ์ ์ ์์ต๋๋ค.
Intersection Observer๋ ๋ณธ๊ฒฉ์ ์ธ ํ์ค์ผ๋ก ๋์๊ฐ๊ณ ์์ผ๋ฉฐ Chrome 51 ์ด์, Edge 15 ์ด์ ๋ฐ Firefox 55 ์ด์์์ ์ด๋ฏธ ์ง์๋๋ฉฐ Safari ์ฉ์ผ๋ก ๊ฐ๋ฐ ์ค์ ๋๋ค. ๋์๋ค polyfill ์ด ์์ต๋๋ค.
์ด์ ๋ต๋ณ
Dan ์ด ์ ๊ณต ํ ๋ต๋ณ ์๋ ์ผ๋ถ ์ํฉ์ ์ ํฉํ์ง ์์ ๋ฌธ์ ๊ฐ์์ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ฌธ์ ์ค ์ผ๋ถ๋ ํ๋จ ๊ทผ์ฒ์ ๋ต๋ณ์์ ์ง์ ๋์์ผ๋ฏ๋ก ๊ทธ์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ ์์์ ๋ํด ์๋ชป๋ ๊ธ์ ์ ์ ๊ณตํฉ๋๋ค.
- ํ ์คํธ์ค์ธ ์์ ์์ ๋ค๋ฅธ ์์๊ฐ ์จ๊ฒจ์ ธ ์์
- ๋ถ๋ชจ ๋๋ ์กฐ์ ์์์ ๊ฐ์ ์์ญ ์ธ๋ถ
- CSS
clip์์ฑ ์ ์ฌ์ฉํ์ฌ ์จ๊ฒจ์ง ์์ ๋๋ ํ์ ์์
์ด๋ฌํ ์ ํ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋จํ ํ ์คํธ ๊ฒฐ๊ณผ์์ ์ค๋ช ๋ฉ๋๋ค .
ํด๊ฒฐ์ฑ
: isElementVisible()
์๋ ํ ์คํธ ๊ฒฐ๊ณผ์ ์ฝ๋์ ์ผ๋ถ์ ๋ํ ์ค๋ช ๊ณผ ํจ๊ป ์ด๋ฌํ ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ์ฑ ์ด ์์ต๋๋ค.
function isElementVisible(el) {
var rect = el.getBoundingClientRect(),
vWidth = window.innerWidth || document.documentElement.clientWidth,
vHeight = window.innerHeight || document.documentElement.clientHeight,
efp = function (x, y) { return document.elementFromPoint(x, y) };
// Return false if it's not in the viewport
if (rect.right < 0 || rect.bottom < 0
|| rect.left > vWidth || rect.top > vHeight)
return false;
// Return true if any of its four corners are visible
return (
el.contains(efp(rect.left, rect.top))
|| el.contains(efp(rect.right, rect.top))
|| el.contains(efp(rect.right, rect.bottom))
|| el.contains(efp(rect.left, rect.bottom))
);
}
ํฉ๊ฒฉ ์ํ : http://jsfiddle.net/AndyE/cAY8c/
๊ทธ๋ฆฌ๊ณ ๊ฒฐ๊ณผ :
์ถ๊ฐ ์ฌํญ
๊ทธ๋ฌ๋์ด ๋ฐฉ๋ฒ์๋ ๊ณ ์ ํ ์ ํ์ด ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋์ผํ ์์น์์๋ ๋ค๋ฅธ ์์๋ณด๋ค ๋ฎ์ z- ์์ธ์ผ๋ก ํ ์คํธ์ค์ธ ์์๋ ์์์๋ ์์๊ฐ ์ค์ ๋ก ์ผ๋ถ๋ฅผ ์จ๊ธฐ์ง ์๋๋ผ๋ ์จ๊ฒจ์ง ๊ฒ์ผ๋ก ์๋ณ๋ฉ๋๋ค. ์ฌ์ ํ์ด ๋ฐฉ๋ฒ์ Dan์ ์๋ฃจ์ ์์ ๋ค๋ฃจ์ง ์๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค.
๋ชจ๋ element.getBoundingClientRect()์ document.elementFromPoint()CSSOM ์์
์ด์ ์ฌ์์ ์ผ๋ถ์ด๋ฉฐ ์ดํ ์ ์ด๋ IE 6์์ ์ง์ํ๊ณ , ๊ฐ์ฅ ์ค๋ซ๋์ ๋ฐ์คํฌํ ๋ธ๋ผ์ฐ์ (ํ์ง ์๋ฒฝํ๊ฒ์ด๊ธฐ๋ํ์ง๋ง). ์์ธํ ๋ด์ฉ ์์ด ๊ธฐ๋ฅ์ ๋ํ Quirksmode ๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
contains()์์ ๋ฐํ ํ document.elementFromPoint()์์๊ฐ ๊ฐ์์ฑ ํ
์คํธ์ค์ธ ์์์ ํ์ ๋
ธ๋ ์ธ์ง ํ์ธํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค . ๋ฆฌํด ๋ ์์๊ฐ ๋์ผํ ์์ ์ธ ๊ฒฝ์ฐ์๋ true๋ฅผ ๋ฆฌํดํฉ๋๋ค. ์ด๊ฒ์ ๋จ์ง ์ํ๋ฅผ ๋์ฑ ๊ฐ๋ ฅํ๊ฒ ๋ง๋ญ๋๋ค. ๋ชจ๋ ์ฃผ์ ๋ธ๋ผ์ฐ์ ์์ ์ง์๋๋ฉฐ Firefox 9.0์ด ๋ง์ง๋ง์ผ๋ก ์ถ๊ฐ๋ฉ๋๋ค. ์ด์ Firefox ์ง์์ ๋ํด์๋์ด ๋ต๋ณ์ ๊ธฐ๋ก์ ํ์ธํ์ญ์์ค.
๊ฐ์์ฑ์ ์ํด ์์ ์ฃผ์์ ๋ ๋ง์ ์ ์ ํ ์คํธํ๋ ค๋ ๊ฒฝ์ฐ (์ : ์์๊ฐ 50 % ์ด์์ผ๋ก ๋ฎ์ฌ ์์ง ์์์ง ํ์ธํ๋ ค๋ฉด) ์๋ต์ ๋ง์ง๋ง ๋ถ๋ถ์ ์กฐ์ ํ๋ ๋ฐ ๋ง์ ์๊ฐ์ด ๊ฑธ๋ฆฌ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ ํฝ์ ์ 100 % ๋ณผ ์ ์๋์ง ํ์ธํ๋ฉด ์๋๊ฐ ๋งค์ฐ ๋๋ ค์ง ์ ์์ต๋๋ค.
๋ต๋ณ
๋๋ Dan์ ๋๋ต์ ์๋ํ๋ค . ๊ทธ๋ฌ๋ ๊ฒฝ๊ณ๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋์๋ ์์๊ฐ ๋ทฐํฌํธ ํฌ๊ธฐ๋ณด๋ค ์๊ณ ๋ทฐํฌํธ ๋ด๋ถ์ ์์ ํ ์์ด์ผํด์ true์ฝ๊ฒ ์๋ชป๋ ๊ฒฐ๊ณผ ๋ฅผ ๊ฐ์ ธ์ต๋๋ค . ์์๊ฐ ๋ทฐํฌํธ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ ค๋ฉด ryanve์ ๋ต๋ณ ์ด ๊ฐ๊น์ง๋ง ํ
์คํธ์ค์ธ ์์๊ฐ ๋ทฐํฌํธ์ ๊ฒน์น๋ฏ๋ก ๋ค์์ ์๋ํ์ญ์์ค.
function isElementInViewport(el) {
var rect = el.getBoundingClientRect();
return rect.bottom > 0 &&
rect.right > 0 &&
rect.left < (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */ &&
rect.top < (window.innerHeight || document.documentElement.clientHeight) /* or $(window).height() */;
}
๋ต๋ณ
๊ณต๊ณต ์๋น์ค :
Dan์ ์ฌ๋ฐ๋ฅธ ๊ณ์ฐ (ํนํ ํด๋ ์ ํ ํ๋ฉด์์> ์ฐฝ์ผ ์ ์์), ์ฌ๋ฐ๋ฅธ jQuery ํ
์คํธ ๋ฐ isElementPartiallyInViewport ์ถ๊ฐ์ ํจ๊ป ๋๋ตํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ window.innerWidth์ document.documentElement.clientWidth ์ ์ฐจ์ด์ ์ clientWidth / clientHeight๋ ์คํฌ๋กค ๋ง๋๋ฅผ ํฌํจํ์ง ์์ง๋ง window.innerWidth / Height๋ ์คํฌ๋กค ๋ง๋๋ฅผ ํฌํจํ์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค.
function isElementPartiallyInViewport(el)
{
// Special bonus for those using jQuery
if (typeof jQuery !== 'undefined' && el instanceof jQuery)
el = el[0];
var rect = el.getBoundingClientRect();
// DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }
var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
var windowWidth = (window.innerWidth || document.documentElement.clientWidth);
// http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);
return (vertInView && horInView);
}
// http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
function isElementInViewport (el)
{
// Special bonus for those using jQuery
if (typeof jQuery !== 'undefined' && el instanceof jQuery)
el = el[0];
var rect = el.getBoundingClientRect();
var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
var windowWidth = (window.innerWidth || document.documentElement.clientWidth);
return (
(rect.left >= 0)
&& (rect.top >= 0)
&& ((rect.left + rect.width) <= windowWidth)
&& ((rect.top + rect.height) <= windowHeight)
);
}
function fnIsVis(ele)
{
var inVpFull = isElementInViewport(ele);
var inVpPartial = isElementPartiallyInViewport(ele);
console.clear();
console.log("Fully in viewport: " + inVpFull);
console.log("Partially in viewport: " + inVpPartial);
}
ํ ์คํธ ์ฌ๋ก
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Test</title>
<!--
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="scrollMonitor.js"></script>
-->
<script type="text/javascript">
function isElementPartiallyInViewport(el)
{
// Special bonus for those using jQuery
if (typeof jQuery !== 'undefined' && el instanceof jQuery)
el = el[0];
var rect = el.getBoundingClientRect();
// DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }
var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
var windowWidth = (window.innerWidth || document.documentElement.clientWidth);
// http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);
return (vertInView && horInView);
}
// http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
function isElementInViewport (el)
{
// Special bonus for those using jQuery
if (typeof jQuery !== 'undefined' && el instanceof jQuery)
el = el[0];
var rect = el.getBoundingClientRect();
var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
var windowWidth = (window.innerWidth || document.documentElement.clientWidth);
return (
(rect.left >= 0)
&& (rect.top >= 0)
&& ((rect.left + rect.width) <= windowWidth)
&& ((rect.top + rect.height) <= windowHeight)
);
}
function fnIsVis(ele)
{
var inVpFull = isElementInViewport(ele);
var inVpPartial = isElementPartiallyInViewport(ele);
console.clear();
console.log("Fully in viewport: " + inVpFull);
console.log("Partially in viewport: " + inVpPartial);
}
// var scrollLeft = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft,
// var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
</script>
</head>
<body>
<div style="display: block; width: 2000px; height: 10000px; background-color: green;">
<br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br />
<input type="button" onclick="fnIsVis(document.getElementById('myele'));" value="det" />
<br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br />
<div style="background-color: crimson; display: inline-block; width: 800px; height: 500px;" ></div>
<div id="myele" onclick="fnIsVis(this);" style="display: inline-block; width: 100px; height: 100px; background-color: hotpink;">
t
</div>
<br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br />
<input type="button" onclick="fnIsVis(document.getElementById('myele'));" value="det" />
</div>
<!--
<script type="text/javascript">
var element = document.getElementById("myele");
var watcher = scrollMonitor.create(element);
watcher.lock();
watcher.stateChange(function() {
console.log("state changed");
// $(element).toggleClass('fixed', this.isAboveViewport)
});
</script>
-->
</body>
</html>
๋ต๋ณ
getBoundingClientRect ๋ฅผ ์ฌ์ฉํ๋ verge ์์ค๋ฅผ ์ฐธ์กฐํ์ญ์์ค . ๊ทธ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค
function inViewport (el) {
var r, html;
if ( !el || 1 !== el.nodeType ) { return false; }
html = document.documentElement;
r = el.getBoundingClientRect();
return ( !!r
&& r.bottom >= 0
&& r.right >= 0
&& r.top <= html.clientHeight
&& r.left <= html.clientWidth
);
}
๊ทธ๊ฒ์ ๋ฐํํ๋ true๊ฒฝ์ฐ ์ด๋ค ์์์ ์ผ๋ถ๊ฐ ๋ทฐํฌํธ์ ์์ต๋๋ค.
๋ต๋ณ
๋ ์งง๊ณ ๋น ๋ฅธ ๋ฒ์ :
function isElementOutViewport(el){
var rect = el.getBoundingClientRect();
return rect.bottom < 0 || rect.right < 0 || rect.left > window.innerWidth || rect.top > window.innerHeight;
}
๊ทธ๋ฆฌ๊ณ ํ์์ ๋ฐ๋ผ jsFiddle : https://jsfiddle.net/on1g619L/1/