jQuery entire page flickering on certain element - javascript

this is the fiddle:
http://jsfiddle.net/Ywq8G/
I wonder if someone is able to tell me: Why menu1 is flickering after clicking a submenu(the green one) the other two work just fine, but debugging is getting me nowhere and I was like: SO has given me so much answers allready(with just reading) may I contribute and ask my specific question.
I hope the solution will make me a better developer and help others avoid the problems I have encountered.
var MENU_HEIGHT = 110;
$(document).ready(function () {
var menuCollection = {}
var i = 1;
$(".menu").children().each(function () {
menuCollection[i] = [];
$(".subMenu" + i).children().each(function () {
menuCollection[i].push(this);
});
i++;
});
function scroll(menu, item, status) {
if (item < menu.length) {
var currentChild = menu[item];
if (status == "scrollOut") {
$(currentChild).stop().animate({
top: MENU_HEIGHT + 80 * item
}, {
queue: false,
duration: 600
}) {
scroll(menu, item + 1, status);
};
} else {
$(currentChild).stop().animate({
top: 0
}, {
queue: false,
duration: 600
}) {
scroll(menu, item + 1, status);
};
}
}
}
var ii = 1;
$(".menu").children().each(function () {
var target = $(this).attr('class');
var menu = menuCollection[ii];
$("." + target + ", .subMenu" + ii + " > a").bind("mouseover", function () {
doScroll(menu, 0, "scrollOut");
});
$("." + target + ", .subMenu" + ii + " > a").bind("mouseout", function () {
doScroll(menu, 0, "scrollIn");
});
ii++;
});
function doScroll(menu, item, status) {
scroll(menu, item, status);
}
$("a").click(function (event) {
var href = $(this).attr('href');
href = href.substring(1);
$(".current").appendTo(".hidden");
$(".current").removeClass("current");
$("." + href).addClass("current");
$("." + href).appendTo(".main");
$('html, body').animate({
scrollTop: $(".main").offset().top
}, 600);
});
});

There is flickering because you are using href parameter of tag with '#' and when you click on it browsers move window to element with id like #-value. And if you have a lot of content to change browsers first jump to this id and next use your $('html, body').animate({...}) function (so again jump to top and animate to down).
You can change 'href' for example to 'myHref' (in html and js) it's should resolve the problem.
(sorry for my english, i hope is understandable)

Related

Smooth javascript navigation stops working after first click

This webpage http://www.eboxlab.net/ has a menu on the left side. What I need to achieve is to be able to go to a page section when the respective menu option is pressed. Here is my code (pretty sure it's quite bad, but I will clean it up later, after I make it work):
navigateMe();
navInit = 1;
navNext = 2;
function navigateMe() {
step = jQuery('ul#navigation li').size();
looper = setInterval(function(){
if(navNext > step + 1) {
navInit = 1;
navNext = 1;
}
var refLink = jQuery('ul#navigation li:nth-child(' + navInit + ') a').attr('href').replace('#', '');
var divLink = jQuery("div[id='" + refLink + "']").offset().top;
jQuery('ul#navigation li:nth-child(' + navInit + ') a').on('click', function() {
jQuery('html, body').animate({
scrollTop: divLink
}, 500);
});
navInit = navNext;
navNext = navNext + 1;
}, 0);
}
However the problem is that it only works once. After you click menu once, it doesn't slide up or down anymore. Please tell me what's wrong with it.
Many thanks in advance.

Keep dropdown open on hover jQuery

I'm making a quick animated drop down. I have it working great when you mouseover and mouseout on the initial button. I just cant get the HTML div that drops down to "hold" when you're hovered on the dropdown itself. here is a fiddle of what I'm doing: http://jsfiddle.net/kAhNd/
here's what I'm doing in the JS:
$('.navBarClickOrHover').mouseover(function () {
var targetDropDown = $(this).attr('targetDropDown');
var targetDropDownHeight = $('#' + targetDropDown).height();
$('#' + targetDropDown).animate({
'height': '200px'
});
}).mouseout(function () {
if ($('.dropdownCont').is(':hover') || $('.navBarClickOrHover').is(':hover')) {
} else {
var targetDropDown = $(this).attr('targetDropDown');
var targetDropDownHeight = $('#' + targetDropDown).height();
$('#' + targetDropDown).animate({
'height': '0px'
});
}
});
It works, but the element doesn't stay dropped down when you have your mouse over it. I added in
if ($('.dropdownCont').is(':hover') || $('.navBarClickOrHover').is(':hover')) {
}
to try to make it do nothing when you're hovered over '.dropdownCont'.
Having a hard time explaining it. I'm sorry, I hope I make sense. Any help would be awesome! here's my Fiddle: http://jsfiddle.net/kAhNd/
Here is your code transformed http://jsfiddle.net/krasimir/kAhNd/3/
var button = $('.navBarClickOrHover');
var isItOverTheDropdown = false;
var showDropDown = function() {
var targetDropDown = $('#' + button.attr('targetDropDown'));
var targetDropDownHeight = targetDropDown.height();
targetDropDown.animate({
'height': '200px'
});
targetDropDown.off("mouseenter").on("mouseenter", function() {
isItOverTheDropdown = true;
});
targetDropDown.off("mouseleave").on("mouseleave", function() {
isItOverTheDropdown = false;
hideDropDown();
});
}
var hideDropDown = function() {
var targetDropDown = $('#' + button.attr('targetDropDown'));
var targetDropDownHeight = targetDropDown.height();
targetDropDown.animate({
'height': '0px'
});
}
$('.navBarClickOrHover').mouseover(function () {
showDropDown();
}).mouseout(function () {
setTimeout(function() {
!isItOverTheDropdown ? hideDropDown : '';
}, 500);
});
I guess that this is what you want to achieve.

jQuery rearrange DOM elements

I'm a little confused why this is not working how it's supposed to.
I have a list of <div>s that wrap around based on the size of the page. But clicking the div it .animate() the width of the clicked div and animates the divs after it closer together and stacks them.
This all works except the last stacked div, despite having plenty of room still gets knocked down to the next row.
please see my code on jsfiddle:
http://jsfiddle.net/ZHYRq/2/
$.each($('.employee-box'), function(i, el) {
$(el).addClass("top-" + (Math.round($(el).offset().top)));
return $(el).css('position', 'relative').attr('data-left', Math.round($(el).offset().left));
});
$('.employee-image').hover(function(e) {
var $employee;
$employee = $(e.target).parents('.employee-box');
if (e.type === 'mouseenter') {
return $($employee.find('a.bio')).addClass('highlight');
} else {
return $($employee.find('a.bio')).removeClass('highlight');
}
});
$('.employee-image, a.bio').click(function(e) {
var $employee, is_expanded, speed;
speed = 150;
$employee = $(e.target).parents('.employee-box');
is_expanded = $employee.hasClass('bio-expanded');
if ($('.bio-expanded').length > 0) {
$.when(collapse_previous_bio(speed)).then(function() {
if (!is_expanded) {
return expand_bio_box($employee, speed);
}
});
} else {
expand_bio_box($employee, speed);
}
return false;
});
var collapse_previous_bio = function(speed) {
var klass;
klass = "." + $('.bio-expanded').attr('class').match(/top-\d{1,5}/)[0];
$('.bio-expanded .bio-block').fadeOut(speed, function() {
$('.bio-expanded').animate({
width: "185px"
}, speed);
$(klass).animate({
left: '0px'
}, speed);
$('.bio-expanded').removeClass('bio-expanded');
});
};
var expand_bio_box = function($employee, speed) {
var curr_left, klass;
klass = "." + $employee.attr('class').match(/top-\d{1,5}/)[0];
curr_left = parseInt($employee.data('left'));
// comment out the $.when block and un-comment out the collapse_others() to see the other elements collapse as they should
$.when(collapse_others(klass, curr_left)).then(function() {
$employee.animate({
width: "392px"
}, speed, function() {
$employee.find('.bio-block').fadeIn(speed);
$employee.addClass('bio-expanded');
});
});
// collapse_others(klass, curr_left)
};
var collapse_others = function(klass, curr_left) {
var left_pos;
left_pos = 0;
$.each($(klass), function(i, el) {
var el_left;
el_left = parseInt($(el).data('left'));
$(el).css({
zIndex: 100 - i
});
if (el_left > curr_left) {
$(el).animate({
left: "-" + left_pos + "px"
}, 100);
left_pos += 100;
}
});
};
I'm not sure what is wrong here. Any thoughts?

Onload method is calling itself more than once on successive reloads to application (var image = new Image(), javascript issue)

I don't understand why onload method(see the code below) is calling itself more than once in IE8 and IE9 browsers on consecutive reloads.
I guess, onload method is fired more than once that is causing this image to render(appear) more than once in IE8,IE9. Below js code is written by my senior Front-Ender (he is using his own written js library for all .append(), anim(), ... methods). The code is working as expected in Firefox, Chrome but the image(html code) is rendering more than once while reloading with a IE8 or IE9 browser.
Some Quick Info:
waitingFor() - Periodically scans dom for matching elements,
mdiTog - The image that is appearing more than once..
How it works:
The div attribute Class="suggestions contextSuggesions" is inserted in the body element and contains an unordered list (ul, li, ul) that toggles between opacity 0 and 1 if you click on the image (mdiTog).
Below is the image of Mditog appearing more than once and it's appearance is random:
waitingFor('.viewport .homePage', function () {
var mdiTog = new Image();
mdiTog.onload = function () {
var $mdi = M$('.mdiTabs ul'),
$contextMenu = M$($body.append('<div class="suggestions contextSuggesions" style="display:none"></div>')),
$toggle = M$($mdi.append('<li class="mdiTog" style="display:none"></li>')),
visible = false,
active = false;
var hideCtx = function () {
if (visible) {
$contextMenu.anim('', {opacity: 100}, {opacity: 0}, 250, function () {
$contextMenu.css({display: 'none'});
});
visible = false;
}
};
$toggle.css({opacity: 0, display: 'inline-block'}).anim('', {opacity: 0}, {opacity: 100}, 1000).on('click', function () {
var togOS = $toggle.offset(),
menu = '';
M$('li', $mdi.get()).each(function (el, idx) {
if (idx > 1) {
menu += '<li rel="' + idx + '">' + $mdi.text(null, el) + '</li>';
}
});
$contextMenu.css({opacity: 0, display: 'block', top: togOS.top + 'px', left: (togOS.left - 20) + 'px'}).anim('', {opacity: 0}, {opacity: 100}, 400, function () {
visible = true;
}).html('<ul>' + menu + '<li class="uiUtil hr" onclick="ApolloUI.widgets.expose.show()">' + translate('previewAll') + '</li><li class="uiUtil" onclick="ApolloUI.mdi.closeAll()">' + translate('closeAll') + '</li></ul>');
});
$contextMenu.on('click', function (e) {
var target = $contextMenu.eventTarget(e);
if (target.tagName === 'LI' && target.className.indexOf('uiUtil') === -1) {
$contextMenu.fire('click', M$('.mdiTabs li').get(parseInt(target.getAttribute('rel'), 10)));
}
hideCtx();
}).on('mouseleave', function () {
active = false;
}).on('mouseenter', function () {
active = true;
});
setInterval(function () {
if (!active && visible) {
hideCtx();
}
}, 1000);
};
mdiTog.src = 'media/img/ico_16_context.png';
});
I do have to close this issue as soon as possible, so any suggestions/modifications/addition in this code to force onload to execute only once on even on several consecutive reloads in IE8/IE9 browsers are welcome.
If the onload fires twice, you should use a guard against executing the handler more than once:
var mdiTog = new Image();
var hasFired = false;
mdiTog.onload = function () {
if (hasFired)
return;
hasFired = true;
…
};
Or, if you're using a jQuery-like library, you could try the one event binding method:
var mdiTog = new Image();
M$(mdiTog).one("load", function () {
…
});

javascript 'over-clicking' bug

I have a bug in Javascript where I am animating the margin left property of a parent container to show its child divs in a sort of next/previous fashion. Problem is if clicking 'next' at a high frequency the if statement seems to be ignored (i.e. only works if click, wait for animation, then click again) :
if (marLeft === (-combinedWidth + (regWidth) + "px")) {
//roll margin back to 0
}
An example can be seen on jsFiddle - http://jsfiddle.net/ZQg5V/
Any help would be appreciated.
Try the below code which will basically check if the container is being animated just return from the function.
Working demo
$next.click(function (e) {
e.preventDefault();
if($contain.is(":animated")){
return;
}
var marLeft = $contain.css('margin-left'),
$this = $(this);
if (marLeft === (-combinedWidth + (regWidth) + "px")) {
$contain.animate({
marginLeft: 0
}, function () {
$back.fadeOut('fast');
});
} else {
$back.fadeIn(function () {
$contain.animate({
marginLeft: "-=" + regWidth + "px"
});
});
}
if (marLeft > -combinedWidth) {
$contain.animate({
marginLeft: 0
});
}
});
Sometimes is better if you create a function to take care of the animation, instead of writting animation code on every event handler (next, back). Also, users won't have to wait for the animation to finish in order to go the nth page/box.
Maybe this will help you:
if (jQuery) {
var $next = $(".next"),
$back = $(".back"),
$box = $(".box"),
regWidth = $box.width(),
$contain = $(".wrap")
len = $box.length;
var combinedWidth = regWidth*len;
$contain.width(combinedWidth);
var currentBox = 0; // Keeps track of current box
var goTo = function(n) {
$contain.animate({
marginLeft: -n*regWidth
}, {
queue: false, // We don't want animations to queue
duration: 600
});
if (n == 0) $back.fadeOut('fast');
else $back.fadeIn('fast');
currentBox = n;
};
$next.click(function(e) {
e.preventDefault();
var go = currentBox + 1;
if (go >= len) go = 0; // Index based, instead of margin based...
goTo(go);
});
$back.click(function(e) {
e.preventDefault();
var go = currentBox - 1;
if (go <= 0) go = 0; //In case back is pressed while fading...
goTo(go);
});
}
Here's an updated version of your jsFiddle: http://jsfiddle.net/victmo/ZQg5V/5/
Cheers!
Use a variable to track if the animation is taking place. Pseudocode:
var animating = false;
function myAnimation() {
if (animating) return;
animating = true;
$(this).animate({what:'ever'}, function() {
animating = false;
});
}
Crude, but it should give you the idea.
Edit: Your current code works fine for me as well, even if I jam out on the button. On firefox.

Categories

Resources