问题
I have a container that have multiple a4 page (number is random) and I want to detect what page I'm currently viewing.
This is my code:
<div class="mycont">
<div id="page1" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page1</h1>
</div>
<div id="page2" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page2</h1>
</div>
<div id="page3" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page3</h1>
</div>
</div>
<div style="position: fixed; bottom: 0; left: 50%; padding: 10px 50px; background-color: #ccc;" id="curpage">cur page 1</div>
And with this script I can detect only 1 page
<script>
$(document).ready(function() {
var target = $("#page2").offset().top;
var interval = setInterval(function() {
if ($(window).scrollTop() >= target) {
$("#curpage").text("cur page 2");
}
}, 250);
});
</script>
How to detect page 3,4... 50,51 etc ?
回答1:
You can use Intersection Observer:
let observer = new IntersectionObserver(function(entries) {
var ele = entries.filter(entry => entry.isIntersecting);
if (ele.length > 0) {
ele = ele[0].target;
console.log('Visible element is now: ' + ele.id);
}
});
document.querySelectorAll('.mycont [id^=page]')
.forEach(ele => observer.observe(ele));
<div class="mycont">
<div id="page1" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page1</h1>
</div>
<div id="page2" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page2</h1>
</div>
<div id="page3" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page3</h1>
</div>
</div>
<div style="position: fixed; bottom: 0; left: 50%; padding: 10px 50px; background-color: #ccc;" id="curpage">cur page 1</div>
回答2:
Here is vanilla JS solution...
Ad class .page
to pages elements on your page, then select child elements (needs to be child cose to check if element is in view port it has to have content visible):
document.querySelectorAll('.page *');
Add scroll event on window, $(document).ready
wont help you here.
And check with element is in is In Viewport with isInViewport
function.
If element is in view port get its page parent id:
page.parentElement.id
References Read the link on how the isInViewport
function work.
var isInViewport = function(elem) {
var distance = elem.getBoundingClientRect();
return (
distance.top >= 0 &&
distance.left >= 0 &&
distance.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
distance.right <= (window.innerWidth || document.documentElement.clientWidth)
);
};
// read the link on how above code works
var findMe = document.querySelectorAll('.page *');
window.addEventListener('scroll', function(event) {
// add event on scroll
findMe.forEach(page => {
//for each .page
if (isInViewport(page)) {
//if in Viewport
document.querySelector('#curpage').innerHTML="cur "+page.parentElement.id;
}
});
}, false);
EXAMPLE:
jsfiddle.net
回答3:
What you are attempting to do is called ScrollSpy. With jQuery, the .scroll()
method will be useful:
https://api.jquery.com/scroll/
Here are some How To references that will get you all the way there:
References:
https://www.w3schools.com/bootstrap/bootstrap_scrollspy.asp
https://www.w3schools.com/bootstrap/bootstrap_ref_js_scrollspy.asp
how to use scrollspy without using bootstrap
回答4:
We can do this dynamically in jQuery so it finds all page divs, works out their position and checks which page is showing on scroll.
- Get all of your page elements dynamically and stop the
top
of each and its id (and any other information you might want to use) in an array:
var mypages = [];
$(".mycont > div").each(function( el ) {
mypages.push({
pageid : $(this).attr("id"),
pagetop : $(this).offset().top
});
});
- In the
$( window ).scroll
event, you can check the current window position against the position of each of your pages like this:
$( window ).scroll(function() {
$.each(mypages, function(i, page) {
if ($(window).scrollTop() >= page.pagetop) {
$("#curpage").text(page.pageid );
console.log('Page: ' + page.pageid + " at " + page.pagetop);
}
});
});
Working Example:
var mypages = [];
// get all your page elements
$(".mycont > div").each(function( el ) {
//...add the id and top position into our array
mypages.push({
pagename : $(this).attr("id"),
pagetop : $(this).offset().top
});
});
$( window ).scroll(function() {
// loop through each page...
$.each(mypages, function(i, page) {
//...and compare its `top` to the window position
if ($(window).scrollTop() >= page.pagetop) {
$("#curpage").text(page.pagename);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="mycont">
<div id="page1" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page1</h1>
</div>
<div id="page2" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page2</h1>
</div>
<div id="page3" style="width: 21cm; height:29.7cm; border: 1px solid; margin: 10px 0">
<h1>page3</h1>
</div>
</div>
<div style="position: fixed; bottom: 0; left: 50%; padding: 10px 50px; background-color: #ccc;" id="curpage">cur page 1</div>
Note, this assumes all child div
s of your .mycont
are pages - if this is not the case in your project, you can easily change the selector to suit.
来源:https://stackoverflow.com/questions/63816420/dynamically-detect-current-div-on-page-scroll-in-jquery-with-random-number-of-di