I'm writing a quiz web ap with an opening heading and then 10 questions that follow it. The div of the opening and the div of each question are all siblings, so I traverse the page by passing current.nextSibling and current.previousSibling to whatever functions I'm using.
Right now I'm trying to create a smooth scroll with jQuery through its 'animate' and 'scrollTop' methods, but it's not working. Does anyone have any thoughts on this? Code attached here, link to fiddle here: https://jsfiddle.net/fjydnc9m/1/
var main = function () {
var root = $('html, body');
var current = document.getElementById("opening");
$('.upButton').click(function () {
$('html, body').animate({ scrollTop:$(current.previousSibling).offset().top}, 2000);
current = current.previousSibling;
});
$('.downButton').click(function() {
$('html, body').animate({ scrollTop: $(current.nextSibling).offset().top}, 2000);
current = current.nextSibling;
});
}
$(document).ready(main);
You've been trying to use jQuery .offset() on a regular HTML DOM element.
See this updated version of the fiddle:
https://jsfiddle.net/fjydnc9m/12/
What I did is to get the prev and next sibling via jQuery and use .offset() on that.
Note that you'll also have to account for the cases where current is the first or last wrapper, or some strange scrolling will take place. You can do this by checking if the length of prevSibling or nextSibling is > 0 before scrolling.
If you log the current variable, you find out that there is a #text sibling that is assigned to the current variable.
Check out this fiddle:
https://jsfiddle.net/fjydnc9m/13/
You can see that I assigned the current variable twice PRIOR to using it in the scrollTop function:
var main = function() {
var root = $('html, body');
var current = document.getElementById("opening");
$('.upButton').click(function() {
current = current.previousSibling;
current = current.previousSibling;
$('html, body').animate({
scrollTop: $(current).offset().top
}, 2000);
console.log(current);
});
$('.downButton').click(function() {
current = current.nextSibling;
current = current.nextSibling;
$('html, body').animate({
scrollTop: $(current).offset().top
}, 2000);
console.log(current);
});
}
$(document).ready(main);
Note that I'm logging the current variable. Remove one of the current assignments and see what the log shows (you will see what's going on).
Related
I am trying to create smooth scrolling to IDs. When I click on a link its ID should be scroll to top (at a certain point of top. Ex: 200px from top) of the page.
I tried it something like this:
var $root = $('html, body');
$('a[href*=#]').click(function() {
var href = $.attr(this, 'href');
$root.animate({
scrollTop: (($(href).offset().top >= 200 ) ? $(href).offset().top : 200)
}, 500, function () {
window.location.hash = href;
});
return false;
});
But it doesn't work and its always scrolling to top of the page.
Hope somebody may help me out.
I guess, the problem is your href, the target will presumably not be found. Maybe you'd be better off to store the element to scroll to in a data attribute, like so:
$('a[href*=#]').click(function(evt) {
evt.preventDefault();
var target = $(this).data('target');
$('html, body').animate({
scrollTop: $(target).offset().top
}, 2000);
});
With an anchor tag like so:
Brilliant rainbow colors
Obviously, the element with the ID somewhere_over_the_rainbow must exist somewhere in your DOM.
This should do the job correctly :
$('a[href*=#]').click(function() {
var href = $.attr(this, 'href');
var top = $(href).offset().top;
$('body').animate(
{
scrollTop: top - 200
},
500
);
return false;
});
Obviously, the item with the id equal to the hash of the anchor must exist.
I want the numbers in the div id's and div classes to loop and be from 0 to however many divs I have.. How can I accomplish this? I've tried to put it in a for loop but it doesn't work for some reason..
$("#bokautbildning0").hide();
$(".boka_btn0").click(function(){
$("#bokautbildning0").slideToggle();
var scrollToId = $(this).attr('href');
$('html, body').animate({
scrollTop: $(scrollToId).offset().top - 270
}, 500);
return false;
});
$("#bokautbildning1").hide();
$(".boka_btn1").click(function(){
$("#bokautbildning1").slideToggle();
var scrollToId = $(this).attr('href');
$('html, body').animate({
scrollTop: $(scrollToId).offset().top - 270
}, 500);
return false;
});
$("#bokautbildning2").hide();
$(".boka_btn2").click(function(){
$("#bokautbildning2").slideToggle();
var scrollToId = $(this).attr('href');
$('html, body').animate({
scrollTop: $(scrollToId).offset().top - 270
}, 500);
return false;
});
Here's the code with the loop I tried:
for ( var i = 0; i < 5; i++ ) {
$("#bokautbildning" + i).hide();
$(".boka_btn" + i).click(function(){
$("#bokautbildning" + i).slideToggle();
var scrollToId = $(this).attr('href');
$('html, body').animate({
scrollTop: $(scrollToId).offset().top - 270
}, 500);
return false;
});
}
This answer was written for an older version of the question and is no longer correct.
The best solution would be to add a class to all those elements and use that instead of ids to run jQuery on. Let jQuery do the work to iterate over all those elements.
For example, give all elements #bokautbildningn the class .bokautbildning and change your javascript code to this:
$('.bokautbildning').hide();
$('.boka_btn1').click(function(){
$('.bokautbildning').slideToggle();
var scrollToId = $(this).attr('href');
$('html, body').animate({
scrollTop: $(scrollToId).offset().top - 270
}, 500);
return false;
});
The jQuery for this would be pretty straightforward if you made use of data attributes. To wit:
Html example:
<div data-number="1"></div>
<div data-number="2"></div>
<div data-number="3"></div>
<div data-number="4"></div>
<div data-number="5"></div>
jquery:
$("div[data-number]").each(function() {
var number = $(this).data("number");
$(this).html(number);
alert(number);
})
To see it in action:
http://jsfiddle.net/uubxj55r/
You need to use Each and just make sure all items have the same class within each section. There is no need to use the numbering system that you are currently using.
$('.MyDivs').each(function(index){ //Loop through all the elements with class of 'MyDivs'
var thisElement = $(this); //get the current element we're on in the loop
thisElement.find('.bokautbildning').slideToggle(); //Find the element with class 'bokautbildning' within the current element in the loop and slideToggle it
thisElement.find('.boka_btn').click(function() { //Find the element with classs 'boka_btn' within the current element in the loop and add a click listener
//Code for click event happens here
});
}
Here's an example: http://jsfiddle.net/o85tk0s3/
I'm trying to get the page to scroll to #news .section-wrap when .paging-navigation a is clicked. I tried inserting the line (as seen below) but couldn't get it to work. Where am I going wrong?
$('#article-list').on('click', '.paging-navigation a', function(e){
e.preventDefault();
var link = $(this).attr('href');
$('#article-list').scrollTo('#news .section-wrap'); // this is the line I added
$('#article-list').fadeOut(500, function(){
$(this).load(link + ' #article-list', function() {
$(this).find('#article-list > *').unwrap().end().fadeIn(500);
});
});
});
You will need to animate html and body and point to the selector within the jQuery animate function. Try this:
$('html, body').animate({
scrollTop: $('#news .section-wrap').offset().top
}, 2000);
Try something like this:
$(".paging-navigation a").click(function(){
$('html, body').animate({
scrollTop: $("#news .section-wrap").offset().top
}, 500);
});
You might need to alter something in this code, either timing or some bug since i could not test it currently.
Hope it is helpful.
scrollTo() is not a native jQuery method. You can use a third part plugin like http://lions-mark.com/jquery/scrollTo/ or http://demos.flesler.com/jquery/scrollTo/ .
As answered on jQuery scroll to element you can also make the page scroll to the target position, like this:
$("#button").click(function() {
$('html, body').animate({
scrollTop: $("#elementtoScrollToID").offset().top
}, 2000);
});
In Demo 01 You can see the Div is Scrolling top of the page with increase height. And I need the same animation with click Buttons, like in Demo 02.
$('.work-showcase').click(function(){
$('.work-showcase').animate({height:'135px'}, 500);
$(this).animate({height:'400px'}, 500,function() {
$("html, body").animate({ scrollTop: $(this).offset().top });
});
});
Not sure if I understand what you want, but see if this Javascript works for you:
var map = {
"slice1": "#post1",
"slice2": "#post2",
"slice3": "#post3",
}
$('.clickable').click(function(){
var postId = map[$(this).attr('id')];
$('.post').animate({height:'50px'}, 500);
$(postId).animate({height:'400px'}, 500,function() {
$("html, body").animate({ scrollTop: $(postId).offset().top });
});
});
See demo at http://jsfiddle.net/xCKPW/1/.
What I think you want to do is have the animation and size change that you currently have get triggered when a button is clicked.
I also suspect you want the action to occur when the image is clicked.
In this case, move the animations into a separate function, and call that function onclick.
Here's your jsfiddle updated with buttons.
http://jsfiddle.net/Jq4Vw/132/
$('.work-showcase, button').click(function(){
moveAndResize($(this).index());
});
function moveAndResize(index){
var item = $('.work-showcase:eq('+index+')');
$('.work-showcase').animate({height:'135px'}, 500);
$(item).animate({height:'400px'}, 500,function() {
$("html, body").animate({ scrollTop: $(item).offset().top });
});
}
This works as long as the indexes are the same. If you want the index of the buttons to be different, add an id tag or something else that you can then pass to the moveAndResize which maps to the index of the item you want to change.
I've made a single page website, with with each div taking up 100% of the page.
At the moment I have some code that takes the user down the page, one div at a time.
$(".box1").click(function(e){
$('html, body').animate({scrollTop:$('.box2').offset().top }, 'slow');
});
$(".box2").click(function(e){
$('html, body').animate({scrollTop:$('.box3').offset().top}, 'slow');
});
$(".box3").click(function(e){
$('html, body').animate({scrollTop:$('.box4').offset().top}, 'slow');
});
$(".box4").click(function(e){
$('html, body').animate({scrollTop:$('.box5').offset().top}, 'slow');
});
Rather than having the user click different divs (box1, box2, etc) each time, can I let the user click the same div (.arrow) every time?
I have attempted this, with the user clicking .arrow to go through the loop:
var boxes = ["box1", "box2", "box3", "box4"];
for (i = 1; i > boxes.length; i++) {
$(".arrow")click(function(e){
$('html, body').animate({scrollTop:$(boxes[i]).offset().top}, 'slow');
});
}
This however is unresponsive, and won't scroll at all. Does anyone know what is wrong with this loop?
Only have one listener on .arrow which has some logic to decide where to go
(function enableArrow() {
var i = 1; // initial box
$(".arrow").click(function (e) {
i = i % 5 + 1; // (0 to 4) + 1 => 1 to 5
$('html, body').animate(
{scrollTop: $('.box'+i).offset().top},
'slow'
);
});
}());
Paul S. is right. What you attempted to do was assigning multiple click handlers to one .arrow element.
Paul S. suggests to define an i variable which will be visible to function (e) closure and will be modified each time you call the closure.
Try Changing like this.Hope this works.
var boxes = [".box1", ".box2", ".box3", ".box4"];
for (i = 0; i < boxes.length; i++) {
$(".arrow")click(function(e){
$('html, body').animate({scrollTop:$(boxes[i]).offset().top}, 'slow');
});
}
Rather than having a click handler per div, why not use event delegation?
$(document).on('click', '.box', function(event) {
$('html, body').animate({
scrollTop: $(event.target).offset().top
}, 'slow');
});
This way you'll only have a single event handler and the event will carry the div that you clicked on the target.