I've got a simple piece of code like this
http://jsfiddle.net/QTa2c/
and all I want is, when user click on some of the last elements in list to show the content,
$('a.showMeThis').click(function() {
$(this).next('.content').slideToggle('fast', function() {
// there's go all the magic
});
});
and it goes outside the viewport (partly or completely) - scroll of the height of div, so he can see all of the content.
I was looking a lot for some logic for this, playing around with position().top, window.innerHeight and more, but it never goes in the way I want…
Hope you guys will help me, take care and have a nice day!
Use .animate() and .offset()
$('a.showMeThis').click(function () {
var $this = $(this);
$this.next('.content').slideToggle('fast', function () {
$('html,body').animate({
scrollTop: $this.offset().top
}, 'slow');
});
});
Fiddle Demo
Updated after OP's comment
Updated Fiddle Demo
$('a.showMeThis').click(function () {
var $this = $(this);
$this.next('.content').slideToggle('fast', function () {
if ($this.position()) {
if ($this.position().top + $this.height() > $(window).scrollTop() + (window.innerHeight || document.documentElement.clientHeight)) {
$('html,body').animate({
scrollTop: $this.position().top - (window.innerHeight || document.documentElement.clientHeight) + $this.height() + 15 + $this.next('.content').height()
}, 100);
}
}
});
});
With condition it looks like this: http://jsfiddle.net/QTa2c/1/
if ($(this).parent().offset().top + $(this).height() > window.innerHeight + $(window).scrollTop())
{
var a = $(this)
$('html,body').animate({scrollTop: $(a).parent().offset().top})
}
I think, this code is enough to understand the logic =)
UPD: note, that you should insert return false; into .click event to prevent jumping to # anchor.
Related
I simply want to scroll a page to the bottom
seems - it is a deep secret
$(window).on('load', function(){
let y = $('body').height();
console.log(y); // 2285
$('document').scrollTop(y);
});
also tried:
$('document').scrollTop(y + 'px');
$('body').scrollTop(y);
$('body').scrollTop(y + 'px');
also tried some code from here - without success
please help
Here is the alternative way. It works for me.
<script>
jQuery(document).ready(function () {
jQuery("button").click(function () {
jQuery("html, body").animate(
{
scrollTop: jQuery("html, body").get(0).scrollHeight,
},
1000
);
});
});
</script>
I'm looking for a code that scrolls up to the top of the currently active panel heading of my bootstrap 3 html/css accordion. The closest solution I've found on stackoverflow is the snippet of js below.
This snippet works fairly well, but when a panel heading gets clicked the page scrolls such that the very top of the panel content is flush with the top of the screen. Is there a way to modify this so that the scrolling effect will result in the panel "heading" (as opposed to the top of panel content area) being visible at the top of the screen?
$(function () {
$('#accordion').on('shown.bs.collapse', function (e) {
var offset = $('.panel.panel-default > .panel-collapse.in').offset();
if(offset)$('html,body').scrollTop(offset.top); }); });
Let me know if I should be sharing the bootstrap accordion html as well.
I used this and it works fine you can adjust the -20 after the .offset().top if you need to tweak it up or down a little.
$(function () {
$('#accordion').on('shown.bs.collapse', function (e) {
var offset = $('.panel.panel-default > .panel-collapse.in').offset();
if(offset) {
$('html,body').animate({
scrollTop: $('.panel-title a').offset().top -20
}, 500);
}
});
});
This is to target the specific .panel-heading clicked as per James Wilson's comment on the accepted answer.
$(function () {
$('#accordion').on('shown.bs.collapse', function (e) {
var offset = $(this).find('.collapse.in').prev('.panel-heading');
if(offset) {
$('html,body').animate({
scrollTop: $(offset).offset().top -20
}, 500);
}
});
});
All I changed from gigelsmith's accepted answer is 'var offset' and the scrollTop's target.
I couldn't get the answer above to work, perhaps I'm missing something but I can't see how the scrollTop line above relates to the currently opened accordion item so used the following code instead. Hope it helps someone else:
$(function () {
$('#accordion').on('shown.bs.collapse', function (e) {
var offset = $('.panel.panel-default > .panel-collapse.in').offset();
if(offset) {
$('html,body').animate({
scrollTop: $('.panel-collapse.in').siblings('.panel-heading').offset().top
}, 500);
}
});
});
Always animate looks a bit too much so this is my version to only do the job when heading is over the visible part.
(note that I use a data-accordion-focus to apply the fix)
$('[data-accordion-focus]').on('shown.bs.collapse', function (e) {
var headingTop = $(e.target).prev('.panel-heading').offset().top - 5;
var visibleTop = $(window).scrollTop();
if (headingTop < visibleTop) {
$('html,body').animate({
scrollTop: headingTop
}, 500);
}
});
By using .panel-default as selector of .on(), you can scroll to the active panel.
$('#accordion').on('shown.bs.collapse', '.panel-default', function (e) {
$('html,body').animate({
scrollTop: $(this).offset().top
}, 500);
});
I'm extremely new to JavaScript so I apologize in advance. I'm trying to create a one page html document for a school project using a list of links for navigation that change when the anchor is scrolled to. I've tried various different methods found on Jfiddle and through stackoverflow. This is the method I am trying now: http://jsfiddle.net/m2zQE/
var topRange = 200, // measure from the top of the viewport to X pixels down
edgeMargin = 20, // margin above the top or margin from the end of the page
animationTime = 1200, // time in milliseconds
contentTop = [];
$(document).ready(function () {
// Stop animated scroll if the user does something
$('html,body').bind('scroll mousedown DOMMouseScroll mousewheel keyup', function (e) {
if (e.which > 0 || e.type == 'mousedown' || e.type == 'mousewheel') {
$('html,body').stop();
}
});
// Set up content an array of locations
$('#nav').find('a').each(function () {
contentTop.push($($(this).attr('href')).offset().top);
});
// Animate menu scroll to content
$('#nav').find('a').click(function () {
var sel = this,
newTop = Math.min(contentTop[$('#nav a').index($(this))], $(document).height() - $(window).height()); // get content top or top position if at the document bottom
$('html,body').stop().animate({
'scrollTop': newTop
}, animationTime, function () {
window.location.hash = $(sel).attr('href');
});
return false;
});
// adjust side menu
$(window).scroll(function () {
var winTop = $(window).scrollTop(),
bodyHt = $(document).height(),
vpHt = $(window).height() + edgeMargin; // viewport height + margin
$.each(contentTop, function (i, loc) {
if ((loc > winTop - edgeMargin && (loc < winTop + topRange || (winTop + vpHt) >= bodyHt))) {
$('#nav li')
.removeClass('selected')
.eq(i).addClass('selected');
}
});
});
});
I'm still not having any luck. I've already searched to see if I could debug the problem and have tried changing the order of the code as well as the order of calling jquery.
Here is a link to the site: https://googledrive.com/host/0BwvPQbnPrz_LMlZDeGlFY2Yydmc/index.html
I used html5boilerplate as a starting point.Thank you in advance.
Don't have much time to look into your code, but when I input the line
Math.min(contentTop[$('#nav a').index($(this))], $(document).height() - $(window).height())
into the console of developer tools, it return NaN.
So I guess the problem is you don't have your scrollTop correctly set.
I suggest you give each element an id and try:
$('html, body').animate({
scrollTop: $("#elementID").offset().top
}, 2000);
or if you insist not giving id,
$('html, body').animate({
scrollTop: $("#container-fulid:nth-child(2)").offset().top
}, 2000);
but notice that this is not working on all browser as the nth-child selector is a CSS3 selector.
Or, if you know how to correctly use other's work, you may try to use bootstrap 3.0, where there is already a function named scrollspy included, which do exactly the thing you are doing.
http://getbootstrap.com/javascript/#scrollspy
I wish someone could help me, I'm a little bit irked about this problem since I've been resolving other issues with this scroll behavior that I'm trying to implement on this site... as you see my sub-menu (on the left) follows the window position as you scroll or you can click any option on the sub-menu wich will trigger an animation, well what seems to be the problem is that everytime I click a second time it won't work, until I re-click it, it will work...
Here's my code
Variables
var startDistance = 210;
var $scrollingDiv = $("#sub-menu");
var position = $("#footer").position();
var height = $("#sub-menu").height();
var pos = position.top - (height + 460);
This is to differ between users and animation scroll
$("body,html").bind("scroll mousedown DOMMouseScroll mousewheel keyup", function(e){
if ( e.which > 0 || e.type === "mousedown" || e.type === "mousewheel"){
if($(window).scrollTop() > startDistance && $(window).scrollTop() < pos) {
$scrollingDiv.stop().animate({
paddingTop: ($(window).scrollTop() - 75) + "px"
}, 'slow');
}
if($(window).scrollTop() == 0) {
$scrollingDiv.stop().animate({
paddingTop: 0
}, 'slow');
}
}
});
Click behavior
$("#sub-menu ul li a").live('click', function(ev) {
var $anchor = $(this);
console.log($anchor.attr('href'));
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 1500,'easeInOutExpo', function() {
$scrollingDiv.stop().animate({
paddingTop: ($($anchor.attr('href')).offset().top - 556) + "px"
}, 'slow');
});
event.preventDefault();
});
It might be the silliest thing but I've been watching my screen for last hour w/o being able to realize what's going on.
Edit: I'm posting my scroll code behavior too because I feel that It might be a global problem and not only related to my click code
Thank you in advance!
[22:00:25.137] ReferenceError: event is not defined # http://altivamedia.com/pruebas/romulos/wp/wp-content/themes/romulos/_/js/functions.js:45
You've accidentally wrote event instead of ev:
});
event.preventDefault();
});
Since event hasn't been defined a ReferenceError gets thrown. Simply use the correct variable:
});
ev.preventDefault();
});
Remark
In order to find such errors on your own use your browser's error console.
This works:
$.fn.center = function () {
this.css("position", "absolute");
this.css("top", ($(window).height() - this.height()) / 2 + $(window).scrollTop() + "px");
this.css("left", ($(window).width() - this.width()) / 2 + $(window).scrollLeft() + "px");
return this
};
$('#container').center();
.. but the element stays in the same position if the window is resized, how do I center it with the resize too?
Thanks
You would need to execute that code in the window resize event. But, if the browser is resized this event fires huge! So it's in general a good idea to create a little "balancer".
$(window).bind('resize', function() {
var that = this;
if(!('balancer' in that) ) {
that.balancer = setTimeout(function() {
$('#container').center();
delete that.balancer;
}, 200);
}
});
This will absorb the many events that are fired when resizing the browser window. In fact, it only calls the .center() at a maximum of 200ms. You probably should even increase that value and cache the node reference to the #container element.
EDIT::
giving percentage to top and left can put at center. but this bad ... really really bad.
$.fn.center = function () {
$(this).css({'position': 'absolute',
'top': '40%',
'left': '40%'
});
};
$(function (){
$('#container').center();
})
On jsfiddle.