How to run the animation only once per page? - javascript

How can I change the following code to run only once per session, and once per page. The div#edgtf-manon-loading-title appears on every page. So, on the second time the same user/session goes to the same page they went before, the animation would NOT load anymore. Thanks!
function edgtfLoadingTitle() {
var loadingTitle = $('#edgtf-manon-loading-title');
if (loadingTitle.length) {
var fallback = edgtf.body.hasClass('edgtf-ms-explorer') ? true : false;
var done = function() {
edgtfEnableScroll();
edgtf.body.addClass('edgtf-loading-title-done');
$(document).trigger('edgtfTitleDone');
};
var toTop = function() {
loadingTitle
.addClass('edgtf-to-top')
.one(edgtf.transitionEnd, done);
};
edgtfDisableScroll();
loadingTitle.addClass('edgtf-load');
if(fallback) {
toTop();
}
loadingTitle.one(edgtf.animationEnd, toTop);
}
}
Is there a way I can add something like this code below to the original? And where exactly?
var yetVisited = localStorage['visited'];
if (!yetVisited) {
//something here
};

Related

How to pass variable asyncronously through different scripts

I can't figure out how to do it.
I have two separate scripts. The first one generates an interval (or a timeout) to run a specified function every x seconds, i.e. reload the page.
The other script contains actions for a button to control (pause/play) this interval.
The pitfall here is that both sides must be asyncronous (both run when the document is loaded).
How could I properly use the interval within the second script?
Here's the jsFiddle: http://jsfiddle.net/hm2d6d6L/4/
And here's the code for a quick view:
var interval;
// main script
(function($){
$(function(){
var reload = function() {
console.log('reloading...');
};
// Create interval here to run reload() every time
});
})(jQuery);
// Another script, available for specific users
(function($){
$(function(){
var $playerButton = $('body').find('button.player'),
$icon = $playerButton.children('i');
buttonAction = function(e){
e.preventDefault();
if ($(this).hasClass('playing')) {
// Pause/clear interval here
$(this).removeClass('playing').addClass('paused');
$icon.removeClass('glyphicon-pause').addClass('glyphicon-play');
}
else {
// Play/recreate interval here
$(this).removeClass('paused').addClass('playing');
$icon.removeClass('glyphicon-play').addClass('glyphicon-pause');
}
},
buttonInit = function() {
$playerButton.on('click', buttonAction);
};
buttonInit();
});
})(jQuery);
You could just create a simple event bus. This is pretty easy to create with jQuery, since you already have it in there:
// somewhere globally accessible (script 1 works fine)
var bus = $({});
// script 1
setInterval(function() {
reload();
bus.trigger('reload');
}, 1000);
// script 2
bus.on('reload', function() {
// there was a reload in script 1, yay!
});
I've found a solution. I'm sure it's not the best one, but it works.
As you pointed out, I eventually needed at least one global variable to act as a join between both scripts, and the use of a closure to overcome asyncronous issues. Note that I manipulate the button within reload, just to remark that sometimes it's not as easy as moving code outside in the global namespace:
Check it out here in jsFiddle: yay! this works!
And here's the code:
var intervalControl;
// main script
(function($){
$(function(){
var $playerButton = $('body').find('button.player'),
reload = function() {
console.log('reloading...');
$playerButton.css('top', parseInt($playerButton.css('top')) + 1);
};
var interval = function(callback) {
var timer,
playing = false;
this.play = function() {
if (! playing) {
timer = setInterval(callback, 2000);
playing = true;
}
};
this.pause = function() {
if (playing) {
clearInterval(timer);
playing = false;
}
};
this.play();
return this;
};
intervalControl = function() {
var timer = interval(reload);
return {
play: function() {
timer.play();
},
pause: function(){
timer.pause();
}
}
}
});
})(jQuery);
// Another script, available for specific users
(function($){
$(function(){
var $playerButton = $('body').find('button.player'),
$icon = $playerButton.children('i'),
interval;
buttonAction = function(e){
e.preventDefault();
if ($(this).hasClass('playing')) {
interval.pause();
$(this).removeClass('playing').addClass('paused');
$icon.removeClass('glyphicon-pause').addClass('glyphicon-play');
}
else {
interval.play();
$(this).removeClass('paused').addClass('playing');
$icon.removeClass('glyphicon-play').addClass('glyphicon-pause');
}
},
buttonInit = function() {
$playerButton.on('click', buttonAction);
interval = intervalControl();
};
buttonInit();
});
})(jQuery);
Any better suggestion is most welcome.

Passing functions between RequireJS files

I've got a file which needs to run on page load (randomise_colors.js), but also needs to be called by another file as part of a callback function (in infinite_scroll.js). The randomise_colors script just loops through a list of posts on the page and assigns each one a color from an array which is used on the front-end.
Infinite Scroll loads new posts in to the DOM on a button click, but because the randomise_colors.js file has already ran on page load, new content loaded is not affected by this so I need it to run again. I'm open to other suggestions if it sounds like I could be tackling the problem in a different way, I'm no JS expert.
Currently I'm getting Uncaught ReferenceError: randomise_colours is not defined referring this line of infinite_scroll.js:
randomise_colours.init();
I'm calling all files that need be loaded on document.ready in app.js
require(['base/randomise-colours', 'base/infinite-scroll'],
function(randomise_colours, infinite_scroll) {
var $ = jQuery;
$(document).ready(function() {
infinite_scroll.init();
randomise_colours.init();
});
}
);
This is infinite_scroll.js which initialises Infinite Scroll and features the callback. The callback function runs whenever new items are loaded in via AJAX using the Infinite Scroll jQuery plugin. I've put asterix around the area where I need to run the randomise_colors.init() function from randomise_colors.js.
define(['infinitescroll'], function() {
var $ = jQuery,
$loadMore = $('.load-more-posts a');
function addClasses() {
**randomise_colours.init();**
};
return {
init: function() {
if($loadMore.length >= 1) {
this.setUp();
} else {
return false;
}
},
setUp: function() {
this.initInfiniteScroll();
},
initInfiniteScroll: function() {
$('.article-listing').infinitescroll({
navSelector : '.load-more-posts',
nextSelector : '.load-more-posts a',
itemSelector : '.standard-post'
}, function(newItems) {
addClasses();
});
//Unbind the standard scroll-load function
$(window).unbind('.infscr');
//Click handler to retrieve new posts
$loadMore.on('click', function() {
$('.article-listing').infinitescroll('retrieve');
return false;
});
}
};
});
And this is my randomise_colors.js file which runs fine on load, but needs to be re-called again after new content has loaded in.
define([], function() {
var $ = jQuery,
$colouredSlide = $('.image-overlay'),
colours = ['#e4cba3', '#867d75', '#e1ecb9', '#f5f08a'],
used = [];
function pickRandomColour() {
if(colours.length == 0) {
colours.push.apply(colours, used);
used = [];
}
var selected = colours[Math.floor(Math.random() * colours.length)];
var getSelectedIndex = colours.indexOf(selected);
colours.splice(getSelectedIndex, 1);
used.push(selected);
return selected;
};
return {
init: function() {
if($colouredSlide.length >= 1) {
this.setUp();
} else {
return false;
}
},
setUp: function() {
this.randomiseColours();
},
randomiseColours: function() {
console.log('randomise');
$colouredSlide.each(function() {
var newColour = pickRandomColour();
$(this).css('background', newColour);
});
}
};
});
You would have to reference randomiseColours inside the infiniteScroll file. So you need to change your define function to the following:
define(['infinitescroll', 'randomise-colours'], function(infiniteScroll, randomise_colours)
Remember that when using require you need to reference all variables through the define function, otherwise they will not be recognised.

setInterval does not seem to be working?

This code does not seem to be working. I am trying to create a dynamic list of chat rooms available that updates every 10 seconds. I also want the user to be able to set peraminters to filter what rooms would be shown.
I am using this code, and it does not seem to be working for some reason.
<script type="text/javascript">
function setRooms()
{
console.log('ok');
if($('#only').is(':checked'))
{
var checked = 1;
}
else
{
var checked = 0;
}
if($('#open').is(':checked'))
{
var opened = 1;
}
else
{
var opened = 0;
}
$.post('backend/outputRooms', {
fLevel : $('#flevel').val(),
sLevel : $('#slevel').val(),
display : $('display').val(),
Checked : checked,
},
function(data)
{
$('#text').html(data);
});
}
$(document).ready(function(){
setInterval(setRooms(), 10000);
});
</script>
I have ruled out a problem with the backend page, as the console.log('ok') does not seem to be working as well. Any help?
setInterval(setRooms, 10000);
Try putting quotes around your function:
setInterval('setRooms()', 10000);
Alternatively change your method to:
var setRooms = function()
and you can then use:
setInterval(setRooms, 10000);

Show GIF-Animation after page request in Firefox

I have a simple throbber, that is automatically shown when an ajax request lasts longer than 3 seconds. This throbber consists mainly of an animated GIF-Image.
Now, I want to use the same throbber also for regular links, meaning that when I click a link and it takes the server more than 3 seconds to respond, the throbber is shown.
Unfortunately, it seems that firefox is unable to play the animation, while it is "reloading" the webpage. The javascript is called and fades the throbber correctly in, but is it not spinning.
How can I make firefox play the GIF-Animation while it is loading?
This is the function:
// Throbber manager
function Throbber() { }
Throbber.prototype = {
image : null,
requests : 0,
requestOpened : function(event) {
if (this.requests == 0) {
this.image.src = 'throbber.gif';
}
this.requests++;
},
requestLoaded : function(event) {
this.requests--;
if (this.requests == 0) {
this.image.src = 'throbber_stopped.gif';
}
},
clicked : function() {
request_manager.abortAll();
},
// Called on window load
attach : function() {
this.image = document.getElementById('throbber');
if (this.image && request_manager) {
request_manager.addEventListener('open', [this, this.requestOpened]);
request_manager.addEventListener('load', [this, this.requestLoaded]);
request_manager.addEventListener('abort', [this, this.requestLoaded]);
this.image.onclick = function() { Throbber.prototype.clicked.apply(throbber, arguments); };
}
}
}
var throbber = new Throbber();
window.addEventListener('load', function() { Throbber.prototype.attach.apply(throbber, arguments); }, false);
function SimpleDemo() { }
SimpleDemo.prototype = {
// The AjaxRequest object
request : null,
// Setup and send the request
run : function() {
this.request = request_manager.createAjaxRequest();
this.request.get = {
one : 1,
two : 2
};
this.request.addEventListener('load', [this, this.ran]);
this.request.open('GET', 'xml.php');
var req = requests[this.request.id];
return setTimeout(function() { req.send(); }, 5000);
},
// Triggered when the response returns
ran : function(event) {
alert(event.request.xhr.responseText);
}
}
If you use jQuery:
$("#throbber").show();
/* Your AJAX calls */
$("#throbber").hide();
Check to see when the DOM is ready before calling all your Ajax stuff.
using Prototype:
document.observe("dom:loaded", function() {
//your code
});
using jQuery:
$(document).ready(function() {
//your code
});
Or Refer this: http://plugins.jquery.com/project/throbber
I just tried my old code and found out that this issue does not exist anymore in Firefox 10.0.2

quit loop on JS event

so im a little rusty with my JS, but here is my code...
basically i have an image, that on mouseover, it cycles through a hidden div full of other images... fading it out, replacing the src, and fading back in. it works great. but once it gets through all the images, i want it to start back over and keep looping through them until the mouseout event stops it.
i thought i could just call the function again from within the function cycle_images($(current_image));, but that leads to the browser freaking out, understandably. what is a good method to accomplish this?
$.fn.image_cycler = function(options){
// default configuration properties
var defaults = {
fade_delay: 150,
image_duration: 1500,
repeatCycle: true,
};
var options = $.extend(defaults, options);
this.each(function(){
var product = $(this);
var image = $('div.image>a.product_link>img', product);
var description = $('div.image>div.description', product);
var all_images = $('div.all_images', product);
var next_image = ($(all_images).find('img[src="' + $(image).attr('src') + '"]').next('img').attr('src')) ? $(all_images).find('img[src="' + $(image).attr('src') + '"]').next('img') : $(all_images).children('img').first();;
// mouseover
image.fadeOut(options.fade_delay, function(){
image.attr('src', next_image.attr('src'));
image.fadeIn(options.fade_delay);
});
if (options.repeatCycle){
var loop = function() {
product.image_cycler();
}
setTimeout(loop,options.image_duration);
}
});
};
$(document).ready(function() {
$('div.product').hover(function(){
$(this).image_cycler();
}, function(){
$(this).image_cycler({repeatCycle: false});
});
});
It sounds like you want it to re-cycle and stop on mouseout.
After you define the cycle_images() function, add a flag, repeatCycle
cycle_images.repeatCycle = true;
At the end of the cycle_images function, add a recursive call with a timeout
if (this.repeatCycle) {
var f = function() {
return cycle_images.apply(this, [$current_image]);
}
setTimeout(f,50);
}
Then in mouseout,
cycle_images.repeatCycle = false;

Categories