jQuery animation with interval not working - javascript

Basically I want my piece of code to animate my menu out of the screen hence my -50px on scroll. and when not scrolling animate back in.
This is the code I have so far. but It only works on every time I refresh my browser.
var $menu = $(".sticky-nav");
var topAnim = $menu.css("top");
var scrollStopped;
var fadeInCallback = function () {
if (typeof scrollStopped != 'undefined') {
clearInterval(scrollStopped);
}
scrollStopped = setTimeout(function () {
$( ".sticky-nav" ).animate({
top: "20px"
}, 300);
});
}
$(window).scroll(function () {
if (!$menu.is(":animated") && topAnim == "20px") {
$( ".sticky-nav" ).animate({
top: "-50px"
}, 300);
} else {
fadeInCallback.call(this);
}
});
jsfiddle.net/B997S

I found 2 issues in your code.
Replaced topAnim in the below line with $menu.css("top") as topAnim always returned a constant.
if (!$menu.is(":animated") && $menu.css("top") == "20px") {
Next issue was
scrollStopped = setInterval(function () { // this is the right format
Please check the below link
http://jsfiddle.net/kapilgopinath/B997S/1/

Related

Slide Div Across Page using JQuery/CSS

I have used the following code which makes it every time you click on the div it will animate and move across the page, thus moving the next one across after it.
http://jsfiddle.net/jtbowden/ykbgT/2/
However, I am trying to make it so it automatically scrolls every 3 seconds without having to click. I have tried the following adjustments to the javascript using a timer but it seems to just spazz out and not scroll correctly:
<script>
$('.box').click(function () {
$(this).animate({
left: '-50%'
}, 500, function () {
$(this).css('left', '150%');
$(this).appendTo('#container');
});
$(this).next().animate({
left: '50%'
}, 500);
});
$(document).ready(function ()
{
setInterval(function ()
{
$('.box').click();
console.log("BOX CLICKED.");
}, 3000);
});
</script>
Does anyone have any ideas?
Thanks
Similar to Zack's answer(but simpler, IMHO), I've found that the following works for you
id = 1
setInterval(function(){
$('#box' + id).animate({
left: '-50%'
}, 500, function() {
$(this).css('left', '150%');
$(this).appendTo('#container');
});
$('#box' + id).next().animate({
left: '50%'
}, 500);
id = id <= 5 ? id + 1 : 1;
},4000)
Sorted it by using the following adjustments:
<script>
ActiveDashboards = {};
ActiveDashboards["Projects"] = true;
ActiveDashboards["SHEQs"] = false;
ActiveDashboards["HR"] = false;
function ShowNextDashboard()
{
if (ActiveDashboards["Projects"] == true)
{
//Hide this one.
$('#box1').animate({
left: '-50%'
}, 500, function () {
$('#box1').css('left', '150%');
$('#box1').appendTo('#container');
});
//Show SHEQs one.
$('#box2').animate({
left: '50%'
}, 500);
ActiveDashboards["Projects"] = false;
ActiveDashboards["SHEQs"] = true;
}
else if (ActiveDashboards["SHEQs"] == true)
{
//Hide this one.
$('#box2').animate({
left: '-50%'
}, 500, function () {
$('#box2').css('left', '150%');
$('#box2').appendTo('#container');
});
//Show HR one.
$('#box3').animate({
left: '50%'
}, 500);
ActiveDashboards["SHEQs"] = false;
ActiveDashboards["HR"] = true;
}
else if (ActiveDashboards["HR"] == true)
{
//Hide this one.
$('#box3').animate({
left: '-50%'
}, 500, function () {
$('#box3').css('left', '150%');
$('#box3').appendTo('#container');
});
//Show Projects one.
$('#box1').animate({
left: '50%'
}, 500);
ActiveDashboards["HR"] = false;
ActiveDashboards["Projects"] = true;
}
}
$(document).ready(function ()
{
setInterval(function ()
{
ShowNextDashboard();
}, 4000);
});
</script>
Probably a better way of doing it, but it's working fine and scrolling through each one.

How to combine .with() and .resize() in one script

Can you help me with the following?
I have this working javascript code.
This code makes the bootstrap columns in a row all an equal height for screens with a bigger width than 640px.
if($(window).width() >= 640){
$(document).ready(function () {
$(".row").each(function () {
var highestBox = 0;
$(".col", this).each(function () {
if ($(this).height() > highestBox) highestBox = $(this).height();
});
$(".col", this).height(highestBox);
});
});
}
Problem
The problem is that if I resize the window from less than 640px to more than 640px, I have to refresh the page in order to see the changes. I'd like a script that automatically checks the window size. I think the .resize() function can help me with this but I can't figure out how to implement it.
You could implement it as follows. Put your code inside a function, let's call it resizeMe() .Then:
var rtime,
timeout = false,
waitingTime = 200,
resizeFinished = function () {
if (new Date() - rtime < waitingTime) {
window.setTimeout(resizeFinished, waitingTime);
} else {
timeout = false;
if ($(window).width() >= 640) {
resizeMe();
}
}
};
$(window).resize(function () {
rtime = new Date();
if (timeout === false) {
timeout = true;
window.setTimeout(resizeFinished, waitingTime);
}
}).resize();
With this function, your function resizeMe() is fired only when the resizing process has finished. That way it is assured that resizeMe()isn't fired at every mouse move but only if waitingTime is reached (200ms). This is quite important for performance. (Thanks to urban pointing at)
You could use following snippet, using window.matchMedia() (support & polyfill) method and binding handler in load/resize window events:
$(window).on('load resize', function() {
clearTimeout(this.resizeTimeout);
this.resizeTimeout = setTimeout(function() {
if (window.matchMedia("(min-width: 640px)").matches) {
$(".row").each(function() {
var highestBox = Math.max.apply(null, $(this).find('.box').map(function() {
return this.clientHeight; // or $(this).height()
}));
$(this).find('.box').height(highestBox);
});
}
}, 50);
});
EDIT Adding debouncing regarding good point done in #Daenu's answer
just make a function and pass it to window
function resizeMe(){
if($(window).width() >= 640){
$(document).ready(function () {
$(".row").each(function () {
var highestBox = 0;
$(".col", this).each(function () {
if ($(this).height() > highestBox) highestBox = $(this).height();
});
$(".col", this).height(highestBox);
});
});
}
}
then attach an event to window and pass your function
window.addEventListener("resize", resizeMe);
you need to put the
$(document).ready(function () on the top before the if($(window).width() >= 640)
you can use
$( window ).resize(function() function
Based on #Daenu's answer. A compressed/simplified version that is reusing the same timeout:
$(function(){
timeout = null
waitingTime = 200
$(window).resize(function(){
// Clear old timeout
if (timeout)
clearTimeout(timeout)
// Set new
timeout = setTimeout(resizeMe, waitingTime);
})
})
function resizeMe(){
$(".row").each(function () {
var highestBox = 0;
$(".col", this).each(function () {
if ($(this).height() > highestBox) highestBox = $(this).height();
});
$(".col", this).height(highestBox);
});
}
The idea is that if resize is fired while there is an active timeout, we cancel the old and re-schedule a new one
Fiddle: https://jsfiddle.net/hq1jd47v/2/

Javascript error if element is not on the page

I want to have a single script file for every page, which has scripts which may or may not be required for that particular page. On my homepage I have this script:
$(function () {
var $select = $('#select');
var $window = $(window);
var isFixed = false;
var init = $('#select').offset().top;
$window.scroll(function () {
var currentScrollTop = $window.scrollTop();
if (currentScrollTop > init && isFixed === false) {
isFixed = true;
$select.css({
top: 0,
position: 'fixed'
});
console.log("fixed");
} else if(currentScrollTop <= init && isFixed === true) {
isFixed = false;
$select.css('position', 'relative');
console.log("unfixed");
}
});
$("#scroll").click(function () {
$('html, body').animate({
scrollTop: $(".jumbo").offset().top + $(".jumbo").height()
}, 300);
});
});
However when this runs on the homepage (which doesnt have the #select element) I get this error and breaks my script:
Uncaught TypeError: Cannot read property 'top' of undefined
How can I get it to not cause errors if that script isnt required on that particual page without having to load it in its own file?
Should I have it call the function on page load?
You can use the length property to check if an element exists:
var init = $select.length ? $select.offset().top : 0;
This will return 0 if the element is not present, otherwise its top offset.

Prevent scrolling jquery script from running twice

I'm new to jquery and have put together the following code to make a DIV appear after a set scroll-down amount. If scrolling back up, the DIV disappears. Optionally, once the DIV has appeared, there is a link to close it. This all works as intended, apart from that I only want the script to run once. At the moment if I scroll back up, the yellow box appears again. How can I ensure the box stays closed? As another option, could I integrate cookies or localStorage?
Many thanks! Russ.
Javascript:
$(function () {
var target = $(".box");
if ($(window).scrollTop() > 30) {
target.hide();
}
$(window).scroll(function () {
var pos = $(window).scrollTop();
if (pos > 30) {
target.stop(true, true).fadeIn('slow');
} else {
target.stop(true, true).fadeOut('slow');
}
});
$('a.close').click(function () {
$($(this).attr('href')).slideUp();
return false;
});
});
Here is the jsfiddle link to my code: jsfiddle link
You can remove the class to ensure the box stays enclosed with removeClass(). Or directly $(".box").remove() after your animation.
You can store this choice with cookie but if the client deletes his cookies, it's lost.
You can remove event scroll from window and for localStorage do something like that:
$(function () {
var target = $(".box");
if ($(window).scrollTop() > 30) {
target.hide();
}
$(window).scroll(function () {
var pos = $(window).scrollTop();
if (pos > 30) {
target.stop(true, true).fadeIn('slow');
} else {
target.stop(true, true).fadeOut('slow');
}
if(localStorage['noNotification'] == 'true'){
$(window).off('scroll');
}
});
$('a.close').click(function () {
$($(this).attr('href')).slideUp();
$(window).off('scroll');
localStorage['noNotification'] = 'true';
return false;
});
});
try this http://jsfiddle.net/AbwXu/4/
var notdisplayed=true;
$(function(){
var target = $(".box");
if($(window).scrollTop() > 30){
target.hide();
}
$(window).scroll(function(){
var pos = $(window).scrollTop();
if(pos > 30 && notdisplayed){
target.stop(true, true).fadeIn('slow');
} else {
target.stop(true, true).fadeOut('slow');
notdisplayed=false;
}
});
$('a.close').click(function() {
$($(this).attr('href')).slideUp();
notdisplayed=false;
return false;
});

Hide div when clicking outside the table

I am quite new to Javascript (intermediate in HTML & CSS), though I am pretty good at working things out on my own by looking up other's examples. Unfortunately, I am having significant trouble with this one.
I have a table displaying 3 links to the viewer. Each link when clicked, slides a hidden div open to the right. When one of the other links are clicked, the opened div slides back to being hidden, and then the other one slides open.
What I am looking for, is to hide the divs again when the mouse is clicked on the link again, and also when the mouse is clicked outside the div (or anywhere on the page, really).
I have tried using "e.stopPropagation" but it doesn't seem to be working for me.
Any help is greatly appreciated - thank you.
I have a jsFiddle that I created for practice:
http://jsfiddle.net/AuU6D/3/
This is my jQuery code:
jQuery(function ($) {
$('a.panel').click(function () {
var $target = $($(this).attr('href')),
$other = $target.siblings('.active'),
animIn = function () {
$target.addClass('active').show().css({
left: -($target.width())
}).animate({
left: 0
}, 500);
};
if (!$target.hasClass('active') && $other.length > 0) {
$other.each(function (index, self) {
var $this = $(this);
$this.removeClass('active').animate({
left: -$this.width()
}, 500, animIn);
});
} else if (!$target.hasClass('active')) {
animIn();
}
});
});
Try
jQuery(function ($) {
$('a.panel').click(function () {
var $target = $($(this).attr('href')),
$other = $target.siblings('.active'),
animIn = function () {
$target.addClass('active').show().css({
left: -($target.width())
}).finish().animate({
left: 0
}, 500);
};
if (!$target.hasClass('active') && $other.length > 0) {
$other.each(function (index, self) {
var $this = $(this);
$this.removeClass('active').animate({
left: -$this.width()
}, 500, animIn);
});
} else if (!$target.hasClass('active')) {
animIn();
} else if ($target.hasClass('active')) {
$target.removeClass('active').finish().animate({
left: -$target.width()
}, 500);
}
});
$(document).click(function(e){
var $target = $(e.target), $active = $('div.panel.active');
if($active.length && $target.closest('a.panel').length == 0 && $target.closest($active).length == 0){
$active.removeClass('active').finish().animate({
left: -$active.width()
}, 500);
}
})
});
Demo: Fiddle
DEMO
$(document).click(function (e) {
if (!$(e.target).hasClass('panel')) {
$('div.panel').removeClass('active').removeAttr('style').css('background', ' #e4e4e4');
}
});
or
DEMO
$(document).click(function (e) {
console.log($(e.target).hasClass('panel'));
if (!$(e.target).hasClass('panel')) {
$('div.panel.active').removeClass('active').finish().animate({
left: -$('#right').width()
}, 500);
}
});

Categories