スクロール可能な領域内のdivの可視の高さを取得する必要があります。私はjQueryにかなりまともだと思いますが、これは私を完全に失望させます。
黒のラッパー内に赤のdivがあるとします。
上の図では、jQuery関数はdivの可視部分である248を返します。
上の図のように、ユーザーがdivの上部をスクロールすると、296が報告されます。
これで、ユーザーがdivをスクロールすると、再び248が報告されます。
明らかに、私の数字は、このデモのように一貫性がなく明確ではありません。または、それらの数字をハードコードするだけです。
私には少し理論があります:
とても簡単に思えますが、頭を包み込むことはできません。明日の朝、別の亀裂を取ります。天才が助けてくれるかもしれないと思った。
ありがとう!
更新:私は自分でこれを考え出しましたが、以下の答えの1つがよりエレガントであるように見えるので、代わりにそれを使用します。好奇心のために、ここに私が思いついたものがあります:
$(document).ready(function() {
var windowHeight = $(window).height();
var overviewHeight = $("#overview").height();
var overviewStaticTop = $("#overview").offset().top;
var overviewScrollTop = overviewStaticTop - $(window).scrollTop();
var overviewStaticBottom = overviewStaticTop + $("#overview").height();
var overviewScrollBottom = windowHeight - (overviewStaticBottom - $(window).scrollTop());
var visibleArea;
if ((overviewHeight + overviewScrollTop) < windowHeight) {
// alert("bottom is showing!");
visibleArea = windowHeight - overviewScrollBottom;
// alert(visibleArea);
} else {
if (overviewScrollTop < 0) {
// alert("is full height");
visibleArea = windowHeight;
// alert(visibleArea);
} else {
// alert("top is showing");
visibleArea = windowHeight - overviewScrollTop;
// alert(visibleArea);
}
}
});
ここに、簡単で汚い概念があります。基本的に、エレメントのoffset().top
をウィンドウの上部と比較し、offset().top + height()
をウィンドウの下部と比較します。
function getVisible() {
var $el = $('#foo'),
scrollTop = $(this).scrollTop(),
scrollBot = scrollTop + $(this).height(),
elTop = $el.offset().top,
elBottom = elTop + $el.outerHeight(),
visibleTop = elTop < scrollTop ? scrollTop : elTop,
visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
$('#notification').text(visibleBottom - visibleTop);
}
$(window).on('scroll resize', getVisible);
fiddle の例
edit-ウィンドウのサイズを変更するときにロジックも実行するための小さな更新。
この小さなfunctionは、要素が(垂直)Viewportに表示されるpx
の量を返します:
function inViewport($el) {
var elH = $el.outerHeight(),
H = $(window).height(),
r = $el[0].getBoundingClientRect(), t=r.top, b=r.bottom;
return Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H));
}
次のように使用します:
$(window).on("scroll resize", function(){
console.log( inViewport($('#elementID')) ); // n px in viewport
});
それだけです。
.inViewport()
プラグイン上記から、ロジックをextractして、次のようなプラグインを作成できます。
/**
* inViewport jQuery plugin by Roko C.B.
* http://stackoverflow.com/a/26831113/383904
* Returns a callback function with an argument holding
* the current amount of px an element is visible in viewport
* (The min returned value is 0 (element outside of viewport)
*/
;(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i,el) {
function visPx(){
var elH = $(el).outerHeight(),
H = $(win).height(),
r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
return cb.call(el, Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H)));
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
のように使用:
$("selector").inViewport(function(px) {
console.log( px ); // `px` represents the amount of visible height
if(px > 0) {
// do this if element enters the viewport // px > 0
}else{
// do that if element exits the viewport // px = 0
}
}); // Here you can chain other jQuery methods to your selector
セレクターは、ウィンドウscroll
およびresize
を動的にリッスンしますが、最初のコールバック関数の引数px
を介して、DOMの準備完了の初期値も返します。
以下は、上記のRoryのアプローチのバージョンです。ただし、jQueryプラグインとして機能するように記述されています。その形式でより一般的な適用可能性があります。素晴らしい答え、ロリー-ありがとう!
$.fn.visibleHeight = function() {
var elBottom, elTop, scrollBot, scrollTop, visibleBottom, visibleTop;
scrollTop = $(window).scrollTop();
scrollBot = scrollTop + $(window).height();
elTop = this.offset().top;
elBottom = elTop + this.outerHeight();
visibleTop = elTop < scrollTop ? scrollTop : elTop;
visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
return visibleBottom - visibleTop
}
以下を使用して呼び出すことができます。
$("#myDiv").visibleHeight();