Menu jumps after page load - javascript

The problem is my menu jumps when new page is loaded (the selected menu item should be perfectly centred. The menu uses the code:
$(document).ready(function(){
/* Menu klik animatie II */
$("nav#menu a").click(function(e) {
e.preventDefault();
var dit = $(this);
$(this).parent().siblings().removeClass("current_page_item");
$(this).parent().addClass("current_page_item");
geselecteerd = $('#menu li.current_page_item').sumOuterWidth(true);
voor = $('#menu li.current_page_item').prevAll().sumOuterWidth(true);
vader = $('#menu').parent().width();
invoegen = parseInt(((vader-geselecteerd)/2)-voor);
$('nav#menu').prev().animate({
width: invoegen + 'px',
}, {
duration: 400,
specialEasing: {
width: 'linear',
height: 'easeOutBounce'
},
complete: function() {
$('#content').fadeTo('fast', 0.01, function() {
document.location = $(dit).attr('href');
});
}
});
});
/* Menu uitlijning: geselecteerde item centraal */
$.fn.sumOuterWidth = function(useMargins) {
var sum = 0;
this.each(function() {
sum += $(this).outerWidth(useMargins);
});
return sum;
};
geselecteerd = $('#menu li.current_page_item').sumOuterWidth(true);
voor = $('#menu li.current_page_item').prevAll().sumOuterWidth(true);
vader = $('#menu').parent().width();
invoegen = parseInt(((vader-geselecteerd)/2)-voor);
$('#menu').before("<div style='width:" + invoegen + "px;float:left'> </div>");
});
I can't really think what I did wrong; the width (from the div before the menu) should be the same on the animated one (before new page is loaded) and on the new loaded page.
Anybody an idea about this?
When I use a different font (Varela Round -> Google web fonts) it doesn't happen.

This jQuery syntax runs the code when the DOM is ready.
$(document).ready(function(){ }
In certain cases you'll want the whole page (and it's image dependencies) to be loaded before your code runs. In those cases us the following:
$(window).load(function() { //code })

Related

scrollTop() flickers when used in loop to fix an element at top of page

Click on the second div and see how it stutters.
Demo: http://jsfiddle.net/mirohristov/76xtt3hm/
$("body").on('click', '.mysection', function(){
var el = $(this);
if($(this).hasClass('active')){
url = $('.active .nectar-button').attr('href');
window.open(url, '_self')
}else{
$("html, body").animate({ scrollTop: el.offset().top+'px' }, 500,function(){
el.addClass('active');
var scroller = setInterval(function(){
$("html, body").scrollTop(el.offset().top);
}, 50); //if i change this to 14 or 1 it works here but in my real case there is more content and images in the divs and it's like 150 here - it's sluggish or flickers
$('.mysection').not(el).removeClass('active');
setTimeout(function(){window.clearInterval(scroller)}, 1000);
});
}
});
In the real project, I'm using divs as pages to display content. The selected div should aligned with top of page while the div above is being 'closed'.
I used a loop to re-set the scrollTop to that of the element position but in my real example it, even though the setTitmeout delay is 14 or 1, it acts like in the demo (at 50 delay).
I belive it's because there's more content and full-width, HD background images that go fullscreen in my actual project. It's as if the setTimeout is updated slower than the CSS animation.
How can I make it smooth? Is it even possible?
Try this (demo)
$('body').on('click', '.mysection', function () {
var scroller,
el = $(this),
html = $('html')[0],
body = $('body')[0];
if ($(this).hasClass('active')) {
url = $('.active .nectar-button').attr('href');
window.open(url, '_self')
} else {
el.one('transitionend', function (e) {
clearInterval(scroller);
});
$('html, body').animate({
scrollTop: el.offset().top + 'px'
}, 500, function () {
el.addClass('active');
scroller = setInterval(function () {
var top = el.offset().top;
html.scrollTop = top;
body.scrollTop = top;
}, 10);
$('.mysection').not(el).removeClass('active');
});
}
});

Closing an active div when clicking a secondary button

I am having issues in closing the active div in my site. When I click menu you will see that a menu panel will slide from the left of the screen. As of now the only way to close it would be to click the x button. But I also have the ability for when you click footer a div will slide up from the bottom. Everything works, but the problem I am having is when the menu is open and you click footer the div will cover the menu instead of closing the menu. Same goes the other way around, when the footer is open and you click menu it will open up as well instead of closing the footer.
I would like for one div to open while closing the other open div. How would go about doing this?
Here is the JS and the full code of the site http://jsfiddle.net/8en2D/21/
$(function(){
window.status=0;
$('#menu').click(function(){
if(window.status==0){
$('#slidingMenu').stop().animate({left:'0px'},500);
window.status=1;
$('body, html').css('overflow','hidden');
}
else{
$('#slidingMenu').stop().animate({left:'-100%'},500);
window.status=0;
$('body, html').css('overflow-y','scroll');
}
});
})
/* 1. FOOTER SLIDEUP
-----------------------------------------------------------------------------------------------
===============================================================================================*/
//Close menu when you click Footer
$('#more').click(function () {
var open = $('header').is('.open');
$('#dropFooter')['slide' + (open ? 'Up' : 'Down')](400);
$('header').animate({
bottom: (open ? '-' : '+') + '=200'
}, 400, function () {
$('header').toggleClass('open');
});
});
$('#menu').click(function () {
if ($('').is('.open')) {
$('')
.removeClass('open')
.animate({
'bottom': "-=200"
}, function () {
var $footer = $('.activetoggle');
if ($footer.length)
$footer
.toggleClass('activetoggle footerButton')
.text('Footer');
});
$('footer').slideUp(400);
}
});
$('.footerButton').click(function () {// Change wording once pressed
var $this = $(this);
$this.toggleClass('footerButton');
if ($this.hasClass('footerButton')) {
$this.text('Footer');
} else {
$this.text('Close');
}
$(this).toggleClass('activetoggle');
});
$(window).resize(function(){ //check when window resize
if($(window).width() < 780){ // check when the window width is less than 780
if ($('header').is('.open')) {
$('header')
.removeClass('open')
.animate({
'bottom': "-=200"
});
$footer = $('.activetoggle');
if ($footer.length) {
$footer.toggleClass('activetoggle footerButton').text('Footer');
}
$('#dropFooter').slideToggle(400);
}
}
});
I was able to tweak your jQuery a bit to make this work. See jsfiddle here. Below I have put the two main functions that I modified.
$('#menu').click(function () {
//new jquery
if ($('header').is('.open')) {
var open = $('header').is('.open');
$('#dropFooter')['slide' + (open ? 'Up' : 'Down')](400);
$('header').animate({
bottom: (open ? '-' : '+') + '=200'
}, 400, function () {
$('header').removeClass('open');
});
if ($('.navFooter button').hasClass('activetoggle')) {
$('.navFooter button').removeClass('activetoggle').addClass('footerButton').text('Footer');
}
}
//back to your exisitng code
if (window.status == 0) {
$('#slidingMenu').stop().animate({
left: '0px'
}, 500);
window.status = 1;
$('body, html').css('overflow', 'hidden');
$('#slidingMenu').addClass('open');
} else {
$('#slidingMenu').stop().animate({
left: '-100%'
}, 500);
window.status = 0;
$('body, html').css('overflow-y', 'scroll');
$('#slidingMenu').removeClass('open');
}
});
$('#more').click(function () {
//new jquery
if ($('#slidingMenu').is('.open')) {
$('#slidingMenu').stop().animate({
left: '-100%'
}, 500);
window.status = 0;
$('body, html').css('overflow-y', 'scroll');
$('#slidingMenu').removeClass('open');
}
//back to existing code
var open = $('header').is('.open');
$('#dropFooter')['slide' + (open ? 'Up' : 'Down')](400);
$('header').animate({
bottom: (open ? '-' : '+') + '=200'
}, 400, function () {
$('header').toggleClass('open');
});
});
The list of issues that contributed to your problem is pretty long and I am fairly certain you still have some extraneous code in the fiddle that is still unnecessary.
Multiple .click() functions - all of your code for the click event of
an element should do in one function
Missing or incorrect jQuery selectors - in one area I found $('')
Lacked a notification class that the menu was open (you had this
implemented for the footer (which was called header)

How to only run a script if the DIV is in view?

I have a script that I wrote:
jQuery(function($) {
$('.count').countTo({
from: 0,
to: '400',
speed: '3000',
refreshInterval: 50,
onComplete: function(value) {
console.debug(this);
}
});
});
I need that script only to run when the container div is visible.
<div class="container">
<div class="count"></div>
</div>
To clarify, the div will always be visible, but when the user scrolls it in to view. Any ideas?
http://www.windycitydigital.net/iconvert/ - Example, at the bottom of the page those counters automatically start. I don't want that script to initiate until the user scrolls into view of them.
Here is an example with the alert activated only when the #mydiv is in view:
This works as you asked. Make sure the window is small so #midiv is not in view from the beginning. And after you scroll down, after the entire #mydiv is visible it will activate the alert from the scroll event.
http://jsfiddle.net/u3eCG/7/
divScroll = $("#mydiv").offset().top + $("#mydiv").height();
$(window).scroll(function(){
lastLineScroll = $("body").scrollTop() + $(window).height();
if (divScroll < lastLineScroll) {
alert("Div is visible");
$(window).unbind("scroll");
}
});
What code shoud hide/show div?For example you can use this code to show div
$('.container').show(0, onContainerVisible);
function onContainerVisible(){
jQuery(function($) {
$('.count').countTo({
from: 0,
to: '400',
speed: '3000',
refreshInterval: 50,
onComplete: function(value) {
console.debug(this);
}
});
});
}
if your browser compatibility requirements support it... MutationObserver might be a good candidate here
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
you could do something like this..
function isViewed(selector) {
var viewport = $(window),
item = $(selector);
var viewTop = viewport.scrollTop(),
viewBtm = viewport.scrollTop() + viewport.height(),
itemTop = item.offset().top,
itemBtm = item.offset().top + item.height();
return ((itemTop < viewBtm) && (itemTop > viewTop));
};
var counter = setInterval(function() {countdown()}, 500);
var countdown = function() {
console.log('are you there?');
if(isViewed('#mydiv')) {
clearInterval(counter);
console.log('yes i am here.'); // call countdown here
}
};
here is a jsfiddle to demonstrate
http://jsfiddle.net/pixelchemist/aLT7w/

slideToggle is creating a wobble at the end of an accordion

Creating an accordion - on the slide - the elements underneath the element that is sliding seem to move down a px and then back up, creating a juddering effect.
$(document).ready(function() {
//Promos banners rotation and accordion
$(function(){
var $accordionList = $('.accordion').find('li');
var numberOfItems = $accordionList.length;
var currentItem = 0;
// Set first item to active
$accordionList.eq(currentItem).addClass('active').find('.content').slideToggle(800, function() {});
// Loops through promos
var infiniateLoop = setInterval(function() {
if(currentItem == numberOfItems - 1){
currentItem = 0;
}
else {
currentItem++;
}
// Remove active class, if is has it, and close content
$accordionList.parent().find('li.active').removeClass('active')
.find('.content').slideToggle(800, function() {
});
// Add active class and open content
$accordionList.eq(currentItem).addClass('active').find('.content').slideToggle(800, function() {
});
}, 4000 );
// Click to show promo
$accordionList.on('click', function () {
// Stop rotation
clearInterval(infiniateLoop);
var $accordionHead = $(this);
// Remove active class, if is has it, and close content
if($accordionHead.hasClass('active')) {
// Do nothing
}
else {
$accordionHead.parent().find('li.active').removeClass('active')
.find('.content').slideToggle(800, function() {
});
// Add active class and open content
$accordionHead.addClass('active').find('.content').slideToggle(800, function() {
});
};
});
});
});
Fiddle here demonstrating the problem
I've seen some suggestions that you fix the height of the content div - but the site is responsive so that won't work.
Ya, I've had this problem before to. My favorite fix is to just make my own .slideToggle()
div = $('div');
height = div.height();
width = div.width();
$('div').click( function() {
if ($(this).hasClass('hidden')) {
$(this).animate({height: "0", width: "0"}, 200).hide().addClass('hidden');
} else {
$(this).animate({height: height, width: width}, 200).show().removeClass('hidden');
}
});
You could even wrap it in a prototype function if you wanted to.

How can I get this function to work after a navigation menu bar link has been clicked?

Inside my function.js file I have two functions: the first one loads my pages using ajax. The other one is for minipulating tabbed content on my home page. Initially, both the functions work. However, when I click on any one of the menu bar links, and then click on the home link to return back to the home page, my tabbed area no longer works. I have a feeling that the organictabs() function is only getting called when index.html is first loaded. How can I change this so that organictabs() is called every time a new page is loaded?
// remap jQuery to $
(function($){})(window.jQuery);
/* trigger when page is ready */
$(document).ready(function (){
initialize();
});
function initialize() {
//Click on nav to load external content through AJAX
$('#topnav a, #bottomnav a').not('#bottomnav #fbcallus a').click(function(e){
e.preventDefault();
$('#pages').load( e.target.href + ' #loadcontent'); //pages finished loading
}); //clicked on nav
//handle AJAX for left nav
$(function() {
$("#tabedarea").organicTabs();
});
}
//Click on nav to load external content through AJAX
// $('#topnav a').click(function(e){
// e.preventDefault();
// $('#pages').load( e.target.href + ' #loadcontent'); //pages finished loading
// }); //clicked on nav
(function($) {
$.organicTabs = function(el, options) {
var base = this;
base.$el = $(el);
base.$navtabs = base.$el.find(".navtabs");
base.init = function() {
base.options = $.extend({},$.organicTabs.defaultOptions, options);
// Accessible hiding fix
$(".hidetabs").css({
"position": "relative",
"top": 0,
"left": 0,
"display": "none"
});
base.$navtabs.delegate("li > a", "click", function() {
// Figure out current list via CSS class
var curList = base.$el.find("a.current").attr("href").substring(1),
// List moving to
$newList = $(this),
// Figure out ID of new list
listID = $newList.attr("href").substring(1),
// Set outer wrapper height to (static) height of current inner list
$allListWrap = base.$el.find(".list-wrap"),
curListHeight = $allListWrap.height();
$allListWrap.height(curListHeight);
if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
// Fade out current list
base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
// Fade in new list on callback
base.$el.find("#"+listID).fadeIn(base.options.speed);
// Adjust outer wrapper to fit new list snuggly
//var newHeight = base.$el.find("#"+listID).height();
//$allListWrap.animate({
// height: newHeight
//});
// Remove highlighting - Add to just-clicked tab
base.$el.find(".navtabs li a").removeClass("current");
$newList.addClass("current");
});
}
// Don't behave like a regular link
// Stop propegation and bubbling
return false;
});
};
base.init();
};
$.organicTabs.defaultOptions = {
"speed": 300
};
$.fn.organicTabs = function(options) {
return this.each(function() {
(new $.organicTabs(this, options));
});
};
})(jQuery);
Making use of the complete function on the jquery load will solve your problem I believe:
function initialize() {
//Click on nav to load external content through AJAX
$('#topnav a, #bottomnav a').not('#bottomnav #fbcallus a').click(function(e){
e.preventDefault();
$('#pages').load( e.target.href + ' #loadcontent', function() { $("#tabedarea").organicTabs(); }); //pages finished loading
});
}

Categories

Resources