J'ai un événement click
déclenché automatiquement d'un autre endroit pour la première fois. Mon problème est qu'il s'exécute trop tôt, car les variables requises sont toujours définies par Flash et les services Web. Donc maintenant j'ai:
(function ($) {
$(window).load(function(){
setTimeout(function(){
$('a.play').trigger("click");
}, 5000);
});
})(jQuery);
Le problème est que 5 secondes pour une personne avec une connexion Internet lente peuvent être trop rapides et inversement, pour une personne avec une connexion Internet rapide, c'est trop lent.
Alors, comment dois-je faire le délai ou le délai d'attente jusqu'à ce que someVariable
soit défini?
Je préférerais ce code:
function checkVariable() {
if (variableLoaded == true) {
// Here is your next action
}
}
setTimeout(checkVariable, 1000);
Ce qui suit va continuer à chercher un peu de variable jusqu'à ce qu'il soit trouvé. Il vérifie toutes les 0,25 secondes.
function waitForElement(){
if(typeof someVariable !== "undefined"){
//variable exists, do what you want
}
else{
setTimeout(waitForElement, 250);
}
}
Voici un exemple où toute la logique d’attente jusqu’à ce que la variable soit définie est reportée à une fonction qui appelle ensuite un rappel qui fait tout ce que le programme doit faire. Si vous devez charger des variables avant de faire autre chose, c -ish moyen de le faire, donc vous séparez le chargement de variable de tout le reste, tout en assurant que «tout le reste» est essentiellement un rappel.
var loadUser = function(everythingElse){
var interval = setInterval(function(){
if(typeof CurrentUser.name !== 'undefined'){
$scope.username = CurrentUser.name;
clearInterval(interval);
everythingElse();
}
},1);
};
loadUser(function(){
//everything else
});
Au lieu d'utiliser l'événement de chargement windows, utilisez l'événement ready du document.
$(document).ready(function(){[...]});
Cela devrait se déclencher lorsque tout dans le DOM est prêt, y compris le contenu multimédia entièrement chargé.
Avec Ecma Script 2017, vous pouvez utiliser asynchrone-wait et en même temps pour le faire.
//First define some delay function which is called from async function
function __delay__(timer) {
return new Promise(resolve => {
timer = timer || 2000;
setTimeout(function () {
resolve();
}, timer);
});
};
//Then Declare Some Variable Global or In Scope
//Depends on you
let Variable = false;
//And define what ever you want with async fuction
async function some() {
while (!Variable)
await __delay__(1000);
//...code here because when Variable = true this function will
};
////////////////////////////////////////////////////////////
//In Your Case
//1.Define Global Variable For Check Statement
//2.Convert function to async like below
var isContinue = false;
setTimeout(async function () {
//STOPT THE FUNCTION UNTIL CONDITION IS CORRECT
while (!isContinue)
await __delay__(1000);
//WHEN CONDITION IS CORRECT THEN TRIGGER WILL CLICKED
$('a.play').trigger("click");
}, 1);
/////////////////////////////////////////////////////////////
De plus, vous n'avez pas à utiliser setTimeout dans ce cas, il vous suffit de rendre la fonction prête asynchrone ...
Chemin plus court:
var queue = function (args){
typeof variableToCheck !== "undefined"? doSomething(args) : setTimeout(function () {queue(args)}, 2000);
};
Vous pouvez également passer des arguments
Vous pouvez utiliser ceci:
var refreshIntervalId = null;
refreshIntervalId = setInterval(checkIfVariableIsSet, 1000);
var checkIfVariableIsSet = function()
{
if(typeof someVariable !== 'undefined'){
$('a.play').trigger("click");
clearInterval(refreshIntervalId);
}
};
Vous pourriez avoir Flash appeler la fonction quand c'est fait. Je ne suis pas sûr de ce que vous entendez par services Web. Je suppose que vous avez un code JavaScript appelant des services Web via Ajax, auquel cas vous sauriez quand ils se terminent. Dans le pire des cas, vous pourriez faire une boucle setTimeout
qui vérifierait toutes les 100 ms environ.
Et la vérification de la définition ou non d'une variable peut être simplement if (myVariable)
ou plus sûre: if(typeof myVariable == "undefined")
Object.defineProperty(window, 'propertyName', {
set: value => {
this._value = value;
// someAction();
},
get: () => this._value
});
ou même si vous souhaitez simplement que cette propriété soit transmise en tant qu'argument à une fonction et n'avez pas besoin qu'elle soit définie sur un objet global:
Object.defineProperty(window, 'propertyName', { set: value => someAction(value) })
Cependant, comme dans votre exemple, vous semblez vouloir effectuer une action lors de la création d'un nœud, je vous suggère de regarder MutationObservers .
J'ai voté @ - dnuttle's answer , mais j'ai fini par utiliser la stratégie suivante:
// On doc ready for modern browsers
document.addEventListener('DOMContentLoaded', (e) => {
// Scope all logic related to what you want to achieve by using a function
const waitForMyFunction = () => {
// Use a timeout id to identify your process and purge it when it's no longer needed
let timeoutID;
// Check if your function is defined, in this case by checking its type
if (typeof myFunction === 'function') {
// We no longer need to wait, purge the timeout id
window.clearTimeout(timeoutID);
// 'myFunction' is defined, invoke it with parameters, if any
myFunction('param1', 'param2');
} else {
// 'myFunction' is undefined, try again in 0.25 secs
timeoutID = window.setTimeout(waitForMyFunction, 250);
}
};
// Initialize
waitForMyFunction();
});
Il est testé et fonctionne! ;)
Gist: https://Gist.github.com/dreamyguy/f319f0b2bffb1f812cf8b7cae4abb47c