I have a structure like the following to create a one page web application, using some scroll functionalities:
<div class="home_section"></div> <!-- 1 -->
<div class="home_section"></div> <!-- 2 -->
<div class="home_section"></div> <!-- 3 -->
<div class="home_section"></div> <!-- 4 -->
I need to scroll to each of the above DIVs when the scroll event starts.
So, for example, when the scroll starts, if the first DIV visible from top is <!-- 2 -->, the body will have to scroll to the DIV <!-- 3 --> automatically.
This is what I am doing:
if ($(this).attr('id') == 'home') {
$(document).on("scrollstart", function (e) {
console.log('scrolling started on home');
e.preventDefault();
var next = $(this).find(".home_section"); //here I need to calculate which is the next DIV to scroll to
$('html, body').animate({
scrollTop: next.offset().top
});
});
}
The problem is that I do not know how to check which is the first .home_section DIV visibile starting from top, so I am unable to calculate which is the next target DIV to scroll to.
Thanks for ay help
I would loop through all the .home_sections divs, and get the first :visible like this
var divs = $(".home_section");
for(var x = 0; x < divs.length; x++){
if($(divs[x]).is(":visible")){
//do what you need here
var me = divs[x];
var next = x < divs.length - 1 ? divs[x] : undefined;
if(next){
//do the scroll
}
//then break the for loop
break;
}
}
This way you have an array of divs, you find the first visible and then you have the reference to the nth+1 div.
Another solution that should work:
var firstVisible = $(".home_section:visible:eq(0)");
var next = $(firstVisible).next();
hope this helps
next div would be $(this).next();
var next = $(this).next();
But you would need to modify this line for it to work for all divs:
if ($(this).attr('id') == 'home')
Modify the line var next = $(this).find(".home_section"); as below to get first div with class "home_section".
var next = $(this).getElementsByClassName("home_section")[0];
Related
So I have a single page where the active menu item gets highlighted when you scroll to its corresponding section.
My code works, but I don't understand why, specifically this part:
document.querySelector('nav a[href="' + anchorID + '"]').classList.add("active");
On window.onscroll the for loop collects all the anchors (nav a) from the menu
Then I get access to individual anchorIDs (hrefs) with:
var anchorID = anchorsArray[i].getAttribute("href");
What I don't understand, is how the .activeclass gets added to the correct anchorID based on the current section inside the viewport — when no comparison is made between the section id and the corresponding anchor href. E.g. the href & section id:
Section 2
<section id="section-2"></section>
..are never compared on scroll.
DEMO: https://jsfiddle.net/zgpzrvns/
All the JS
(function() {
var anchorsArray = document.querySelectorAll("nav a");
var sections = document.querySelectorAll("section");
var sectionsArray = [];
// Collect all sections and push to sectionsArray
for (var i = 0; i < sections.length; i++) {
var section = sections[i];
sectionsArray.push(section);
}
window.onscroll = function() {
var scrollPosition = window.pageYOffset;
for (var i = 0; i < anchorsArray.length; i++) {
// Get hrefs from each anchor
var anchorID = anchorsArray[i].getAttribute("href");
var sectionHeight = sectionsArray[i].offsetHeight;
var sectionTop = sectionsArray[i].offsetTop;
if (
scrollPosition >= sectionTop &&
scrollPosition < sectionTop + sectionHeight
) {
/**
* I don't understand how querySelector finds & adds the active
* class to the correct anchor, when no comparison is made between the
* section ID (that is inside current section in viewport) and the
* anchors ID from anchorsArray
*/
document
.querySelector('nav a[href="' + anchorID + '"]')
.classList.add("active");
} else {
document
.querySelector('nav a[href="' + anchorID + '"]')
.classList.remove("active");
}
}
};
})();
In summary: how is the active class added to correct anchor ID, when the corresponding section ID inside the viewport on scroll (when section ID is never detected inside the scroll event?)
I'm so confused about this, and I bet it's something silly I'm overlooking!
Would greatly appreciate some input! :-)
In short:
It doesn't need to compare any ids, because on scroll you loop over all anchors in your navigation. For each you check, if the section at the same index is in the viewport. If so, you add the active class.
If you switch the positions of your navigation items, you'll see that it will add the active class to the wrong item, because it just checks the index.
If you need some more explanation, tell me. Going to edit the answer then.
Edit index explanation:
You have your navigation anchors in an array, and also your sections.
var anchorsArray = document.querySelectorAll("nav a");
var sections = document.querySelectorAll("section");
You are looping your anchors array
for (var i = 0; i < anchorsArray.length; i++) {
and then you get the height and top position of your section at the same index as your anchor (variable i)
var sectionHeight = sectionsArray[i].offsetHeight;
var sectionTop = sectionsArray[i].offsetTop;
if (
scrollPosition >= sectionTop &&
scrollPosition < sectionTop + sectionHeight
) {
and then you set the active class if its true, or remove it, if its false.
So on each scroll your code does the following:
Get anchor one -> check if section one is in range -> If yes -> add active -> else remove active
Get anchor two -> check if section two is in range -> If yes -> add active -> else remove active
Get anchor three -> ... and so one
I've created this little fancy jQuery Snippet to toggle the class of an element in an interval:
setInterval(function(){$('.grid-item .slide-image').toggleClass('active')}, 800);
The script works fine! Now I got multiple elements with the base-class .slide-image in the wrapper .grid-item.
<div class="grid-item">
<div class="slide-image"><img src="http://www.placehold.it/500x500/233953"></div>
<div class="slide-image"><img src="http://www.placehold.it/500x500/03144b"></div>
<div class="slide-image"><img src="http://www.placehold.it/500x500/030a4b"></div>
</div>
Is there a way to rewrite the snippet so the second .slide-image gets the class .active after the first one? Then the third element and so on...
The Problem: The amout of .slide-image-elements is no defined. In some cases there are two of them, in another there are four elements.
Check out my CodePen!
Try this
var slides = $('.grid-item .slide-image'), // cache slides
counter = 0; // global counter
setInterval(function(){
slides.removeClass('active'); // remove active class
slides.eq(counter).addClass('active'); // add active class
counter++;
if (counter == slides.length) counter = 0; // reset counter after last slide
}, 800);
Updated CodePen
You can check if current active element id last or not. if it is, then show first element in set else show next sibling element:
$(function(){
var slides = $('.grid-item .slide-image');
setInterval(function(){
var currentactive = $('.active');
var _target = currentactive.is(':last-child') ? slides.first() : currentactive.next();
slides.removeClass('active')
_target.addClass('active')
}, 800);
});
Working Demo
Objective
What method to use to make item 3 move to another container.
Then if click again return the item to previous position
this function should be apply to all items.
Jquery
$('#item3').click(function(){
// What method to use to make item_1 move to another container.
// Then if click again return the item to previous position
});
Check DEMO
HTML
<div id="start">
<div class="element">one</div>
<div class="element">two</div>
<div class="element">three</div>
</div>
<div id="target"></div>
jQuery
$('.element').click(function() {
var cont = $(this).parent().attr('id');
if (cont == 'start') {
var place = '#target';
} else {
var place = '#start';
}
$(place).append($(this));
});
you can use drag and drop plugin of jquery UI.
if you cont want use this then you can try this code by onClick finction....
.JS
function onclickIteam(iteamId){
var x = if('#iteamId').html();
if(if('#iteamId').parent().prop("id") == "my_inventory"){
//$('#iteamId').detach();
$('#server_inventory').append(x);
}else{
//$('#iteamId').detach();
$('#my_inventory').append(x);
}
`}`
I have a specific question about .scrollTop. I have a div with a specific height and a lot of p tags inside:
<div id="scroll">
<p>name1</p>
<p>name2</p>
<!-- till name50 -->
</div>
depending on the name you click it gets a class .active. What I then want to do is scroll the div so, that the name is at the top. So what I get is that I can use scrollTop in an animate function like this:
$('#scroll').animate({scrollTop: value });
but how can I get the var value. I tried it with
var value = $('#scroll p').hasClass('active').position().top;
But somehow it does not work.
Some help is much appreciated.
You need to check scrollTop() for the container #scroll and add that back to the position() arg.
var $scroll = $('#scroll');
$('p').click(function(e){
var $this = $(this);
$scroll.animate({
"scrollTop": $this.position().top + $scroll.scrollTop()
}, 1000);
});
http://jsfiddle.net/yCEap/1/
To just get the value:
var value = $('#scroll').scrollTop();
I know there are a ton of questions on here about jquery image carousel, but they all refer to a plugin. I would like to make one from scratch. It's a pretty simple one, there are 2 buttons, one left and one right. when you click the left button, the position of the overall container that has all the images shifts to the left, and the right makes it go right.
This is what I have so far... Right now the problem is only the left button works. (the right button works only once you slide the image to the left once) And I also want it to animate across all the images, and go to the last image when you get to the end of the set of images
JS:
total_entries = $("image-entry").length;
var current_index = 0;
var slider_entries = $('#slider-entries');
$('#home-slider #left').click(function(){
go_to_index(current_index-1);
return false;
});
$('#home-slider #right').click(function(){
go_to_index(current_index+1);
return false;
});
var go_to_index = function(index){
if(index < 0)
index = total_entries - 1;
if(index > total_entries - 1)
index = 0;
if(current_index == index)
return;
var left_offset = -1 * index * 720;
slider_entries.stop().animate({"left": left_offset}, 250);
//description_container.stop().animate({"left":left_offset}, 250);
current_index = index;
};
HTML:
<div id="slider">
<div id="slider-entries">
<div class="image-entry">
<img src="http://placekitten.com/720/230" />
</div>
<div class="image-entry">
<img src="http://placedog.com/720/230" />
</div>
<div class="image-entry">
<img src="http://placedog.com/720/230" />
</div>
</div>
</div>
total width of each image is 720px
total with of slider-entries is
Thanks
You have a problem with the total_entries variable.
First of all you need a "var" in front, to define that it's a new variable.
Second, you forgot a "." (dot) to search for the class in your HTML code..
your first line should be:
var total_entries = $(".image-entry").length;
Hope it works ;-)