Set delay or timeout before initializing - javascript

I'm working with a script that needs to delay (or have a setTimeout) before any animation loads or initializes, but can't seem to figure out where to put it.
As for delay, if I'm not mistaken, this is used mainly with jquery...So for example: $('id or class here').delay(2000); ...Correct?
As for the setTimeout, if I'm not mistaken, it would be with javascript correct? If so, wouldn't it look something similar to this: setTimeout(function () {function_name},2000); or a slightly different variation of that?
Regardless of these two approaches and trying to add it where I think it should go (using either variations mentioned above), for some reason it just doesn't work right. The console isn't really helping either to check for errors.
In a nutshell, I'm trying to set a delay of 2s (2000ms) before anything starts or initializes.
JS CODE (Where I believe the issue lies):
$(document).ready(function() {
// Additional code here...
// start
BG.init();
// Additional code here...
}
});

Where you have this:
$(document).ready(function() {
Put this:
$(document).ready(function() {
setTimeout(function() {
And then where you have this:
});
// wrapper for background animation functionality
var BG = {
Put this:
}, 2000);
});
// wrapper for background animation functionality
var BG = {
And then, if you don't want to incur the wrath of everyone in the world, indent the stuff inside that new function we just created by one more level. 'Cause indentation is the stuff of life.

There's a lot of 'useless' code for us to help you. Next time share only on a need-to-know bases :)
I've edited your $document.ready block to include the timeout, have a look-see:
$(document).ready(function() {
function initiationProcess() {
// setup logo image
BG.logo = new Image();
BG.logo.onload = function() {
BG.logo_loaded = true;
BG.showLogo();
}
// /../ more code /../
// wire ticker listener
Ticker.addListener(BG.tick);
// start
BG.init();
// /../ more code /../
}
setTimeout(initiationProcess, 2000);
});
Edit:
I'd also like to note that it's considered bad practise (not to mention that it might result in buggy code) to only partly use semicolons in your script file. There's points and counterpoints to using semicolons, but pick a standard and stick to it!

Related

Meteor Collection.find() blocks the entire application during working

I try to display a loading alert on Meteor with modal package during loading of data.
'change .filterPieChart': function(evt){
Modal.show('loadingModal');
/* a little bit of work */
var data = MyCollection.find().fetch(); // takes 3 or 4 seconds
/* lot of work */
Modal.hide('loadingModal');
}
Normally, the alert is displayed at the beginning of the function, and disappears at the end. But here, the alert appears only after the loading time of the MyCollection.find(), and then disappears just behind. How to display it at the beginning of the function ??
I tried to replace Modal.show with reactive variable, and the result is the same, the changing value of reactive variable is detect at the end of the function.
From what you describe, what probably happens is that the JS engine is busy doing your computation (searching through the collection), and indeed blocks the UI, whether your other reactive variable has already been detected or not.
A simple workaround would be to give some time for the UI to show your modal by delaying the collection search (or any other intensive computation), typically with a setTimeout:
Modal.show('loadingModal');
setTimeout(function () {
/* a little bit of work */
var data = MyCollection.find().fetch(); // takes 3 or 4 seconds
/* lot of work */
Modal.hide('loadingModal');
}, 500); // delay in ms
A more complex approach could be to decrease the delay to the bare minimum by using requestAnimationFrame
I think you need to use template level subscription + reactiveVar. It is more the meteor way and your code looks consistent. As i can see you do some additional work ( retrive some data ) on the change event. Make sense to actually really retrive the data on the event instead of simulation this.
Template.TemplateName.onCreated(function () {
this.subsVar = new RelativeVar();
this.autorun( () => {
let subsVar = this.subsVar.get();
this.subscribe('publicationsName', this.subsVar);
})
})
Template.TemplateName.events({
'change .filterPieChart': function(evt){
Template.instance().collectionDate.subsVar.set('value');
Modal.show('loadingModal');
MyCollection.find().fetch();
Modal.hide('loadingModal');
}
})
Please pay attention that i didn't test this code. And you need to use the es6 arrow function.

document.getElementById always returns "null" for ribbons

I need to set the background color of one of the buttons in the form's ribbon. This isn't supported through Ribbon Workbench, so I have written following javascripts to achieve the same:
function setOpportunityRibbonsAppearance() {
var submitToForeCastButton = parent.document.getElementById("opportunity|NoRelationship|Form|sfw.opportunity.Button1.Button");
if (submitToForeCastButton != null) {
submitToForeCastButton.style.backgroundColor = "lightyellow";
}
}
I have registered this scripts in Form Load event. However the issue is that, I always get parent.document.getElementById as null only.
Surprisingly, I am able to see the control while running the parent.document.getElementById statement in the browser's console, and can also change the styling attributes.
Can anyone please suggest what could be wrong here?
P.S. - I understand document.getElementById is not recommended to use in CRM, however, I am left with no other choice while trying to change the appearance of some of the buttons.
Any help on this, will be much appreciated.
You could upload an icon with a yellow background, to keep everything supported. You won't see text on yellow but it might work for you. Easy and standard.
To keep it unsupported and ugly, you could just keep on trying until you make it, setInterval allows for a function to be repeated:
function setOpportunityRibbonsAppearance() {
var submitToForeCastButton = null;
var interval = setInterval(function(){
submitToForeCastButton = parent.document.getElementById("opportunity|NoRelationship|Form|sfw.opportunity.Button1.Button");
if(submitToForeCastButton != null) {
submitToForeCastButton.style.backgroundColor = "lightyellow";
clearInterval(interval);
}
}, 500); // Every 500ms. Adjust as needed, not too fast or browser will choke.
}
Its probably because your script is running before the page is fully loaded.
Try adding a delay to the to the function Put a Delay in Javascript

Why does waitForKeyElements() only trigger once despite later changes?

For several years I've used the waitForKeyElements() function to track changes in webpages from a userscript. However, sometimes I've found it doesn't trigger as expected and have worked around out. I've run into another example of this problem, and so am now trying to figure out what the problem is. The following is the barest example I can create.
Given a simple HTML page that looks like this:
<span class="e1">blah</span>
And some Javascript:
// function defined here https://gist.github.com/BrockA/2625891
waitForKeyElements('.e1', handle_e1, false);
function handle_e1(node) {
console.log(node.text());
alert(node.text());
}
setInterval(function() {
$('.e1').text("updated: "+Math.random());
}, 5000);
I would expect this code to trigger an alert() and a console.log() every 5 seconds. However, it only triggers once. Any ideas?
Here's a codepen that demonstrates this.
By design and default, waitForKeyElements processes a node just once. To tell it to keep checking, return true from the callback function.
You'll also want to compare the string (or whatever) to see if it has changed.
So, in this case, handle_e1() would be something like:
function handle_e1 (jNode) {
var newTxt = jNode.text ();
if (typeof this.lastTxt === "undefined" || this.lastTxt !== newTxt) {
console.log (newTxt);
this.lastTxt = newTxt;
}
return true; // Allow repeat firings for this node.
}
With the constant string comparisons though, performance might be an issue if you have a lot of this on one page. In that scenario, switching to a MutationObserver approach might be best.

Js Animation using setInterval getting slow over time

I have a web site which displays a portfolio using this scrollbar http://manos.malihu.gr/jquery-custom-content-scroller/ .
I want to have an automatic scroll when the page is
fully loaded. When a user pass over the portfolio it stops the scroll and whe, he leaves it starts moving again.
It currently works well but sometimes it's getting slow or sluggish randomly.
Is there something wrong with my js function?
Here's the page having problems : http://www.lecarreau.net/new/spip.php?rubrique5 (I need the change the hosting provider, I know the site is slow).
This is the function:
(function($){
var timerId = 0;
$(window).load(function(){
$("#carousel").show().mCustomScrollbar( {
mouseWheel:false,
mouseWheelPixels:50,
horizontalScroll:true,
setHeight:370,
scrollButtons:{
enable: true,
scrollSpeed:50
},
advanced:{
updateOnContentResize:true
}
});
timerId = setInterval(function(){myTimer()},50);
$('#carousel').mouseenter(function () {
clearInterval(timerId);
});
$('#carousel').mouseleave(function () {
timerId = setInterval(function(){myTimer()},50);
});
});
})(jQuery);
function myTimer()
{
var width = $(".mCSB_container").width();
var left = $(".mCSB_container").position().left;
if (width-left>0) {
var scrollTo = -left+4;
$("#carousel").mCustomScrollbar("scrollTo", scrollTo);
}
}
Is there something obvious I'm missing?
Timing in the browser is never guaranteed. Since all functionality contents for time on a single event loop, continuous repeated tasks sometimes get a little janky.
One thing you could do that might decrease the jank is to cache the jQuery objects you're creating every 50ms:
var mCSBContainerEl = $(".mCSB_container");
var carouselEl = $("#carousel")
function myTimer()
{
var width = mCSBContainerEl.width();
var left = mCSBContainerEl.position().left;
if (width-left>0) {
var scrollTo = -left+4;
carouselEl.mCustomScrollbar("scrollTo", scrollTo);
}
}
Selecting these to elements only needs to happen once. From there they can just reference a variable instead of having to find the element on the page and wrap it in jQuery again and again.
Caching the variable in this case depends on them being in the DOM when the code runs, which isn't guaranteed here. You may have to move the variable assignment and function declaration into the function passed to load.
Also, as John Smith suggested, consider checking out requestAnimationFrame. Here's a shim I use by Paul Irish: http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

Delaying CreateJS Animation Timeline

I'd been using Swiffy to output .fla files pretty easily, but then I was tipped off that the display would alternate "flashing" white over half the project if viewed in Landscape Mode on a iPad. Very strange behavior, which I couldn't replicate on any other device.
So, I've moved on to trying to use CreateJS to fix the issue. I only know enough JS at this time to get by editing code developed by others, so I've been very ineffective so far.
I've gotten this far:
/* js
this.stop();
var t=setTimeout(function(){(this.play())}, 1000);
*/
or
/* js
this.stop();
setTimeout(this.play(), 1000);
*/
I've not been able to get the animation to mind the timeout, and I've tried MANY different variants to try and make some magic happen. All it does is immediately loads the next frame, it doesn't pause at all. Where am I going wrong here?
Here is the original Actionscript:
stop();
var shortTimer:Timer=new Timer(1000);
shortTimer.addEventListener(TimerEvent.TIMER, timerN1);
shortTimer.start();
function timerN1(e:TimerEvent):void{
play();
shortTimer.reset();
}
Any help would be very appreciated, as I've gotten no where on my own trying to fix this is in my off time for several weeks, and my client is becoming increasingly angry. More of a designer, still very uneducated as far as programming is concerned. Again, even a suggestion would be super helpful at this point. Can't seem to crack it.
This syntax is more correct:
/* js
this.stop();
var t=setTimeout(function(){(this.play())}, 1000);
*/
However, you may find that "this" is Window, not the MovieClip that calls it. You can get around this by using a local reference (in this case, its "_this").
/* js
this.stop();
var _this = this;
var t=setTimeout(function(){
console.log(this, _this);
_this.play();
}, 1000);
*/
You can test this by looking at your console, and seeing what the difference between "this" and "_this" is.
Cheers.
Could you possibly post more of the code you are working with? Have you tried using the onAnimationEnd function:
var _this = this;
_this.onAnimationEnd = function() {
_this.stop();
setTimeout(function(){
_this.play();
}, 1000)
}
Try this to keep your scope alive inside your setTimeout function :
sprite.on('animationend', function(event) {
event.target.stop();
setTimeout(animationend.bind(event.target), 1000);
});
function animationend() {
this.gotoAndPlay('run');
}
With the use of .bind() you can pass an object as the scope in the called function. More information here.

Categories