Will HTML elements have a load success promise? [closed] - javascript

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
While getting used to the concept of promises I have been wondering if elements like HTMLImageElement will have a native promise in future for a 'load' success or failure, similar to the 'load' event which already exists, but with the advantages of being able to be polled after loading?
https://www.w3.org/2001/tag/doc/promises-guide#one-time-events

Promises are definitly a good idea. The problem however is that the DOM has an event model and events and Promises don't really work well together. You can't have a promise for an onclick event for instance (well, you can, but what does it mean?) Some events, like load, may seem to make sense but what if you change the src? You'll get another load event!
Maybe someone is going to have a good idea how to unify these concepts. For now, I think we're stuck with writing code that interfaces between events and Promises.

Not as of HTML5. But I like the concept. I would love to see promise-events in HTML6.
The document you referenced is a guide for when to use promises. So, if you are creating a custom object with events, you might consider implementing a promise interface for your one-time events.
You could easily implement a library to add promise events to DOM elements today.
function loadPromise(image) {
if (image.src && image.complete) {
if (image.naturalWidth > 0) {
return Promise.resolve(image);
}
else {
return Promise.reject(new Error("image failed loading"));
}
}
return new Promise(function(resolve, reject) {
image.addEventListener("load", function(e) {
resolve(image);
}, false);
image.addEventListener("error", function(e) {
reject(new Error("image failed loading"));
}, false);
if (image.src) {
// IE reports image.complete as false when there is an error
var errTest = new Image();
errTest.onerror = function(e) {
reject(new Error("image failed loading"));
};
errTest.src = image.src;
}
});
}

Related

Javascript reloading page after api fetch complette [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 months ago.
Improve this question
I am currently working on a Worlde clone written in JavaScript. I used the rapid API to fetch the five letter word in a function called getWord.
I also used a function called onceADay so the getWord function only gets called once. At the end of the onceAday function, I call location.reload(), so once a new word has been loaded, the website should refresh itself, hence you can start the game again. My problem is that the reload page function runs so quickly that it doesn’t let the fetch get a new word. I tried async/await but it did not work. I also tried to delay to refresh.. but it doesn't work reliably. I also tried to save the last word in a localObject and implement a while loop in the onceADay function.. so while the previousword is equal to current word it should repeat the fetch. but it just crashed the whole site. At this point I am clueless about how I could fix it. I just run out of options here. I am quite new to JavaScript, so I am hoping maybe someone who has more experience could give me a solution. I got the whole project on my git repo ( https://github.com/dodoo86/WordleJS )
Also, here’s the functions I mentioned above.
This is how I fetch the word using async await
async function fetchWordJSON() {
const response = await fetch('https://squirrelle.onrender.com/word');
const word = await response.json();
return word;
}
Than I check if a day passed
function hasOneDayPassed() {
var date = new Date().toLocaleDateString();
if (localStorage.yourapp_date == date)
return false;
localStorage.yourapp_date = date;
return true;
}
Than if so, it should run the following things once a day
function runOncePerDay() {
if (!hasOneDayPassed()) return false;
fetchWordJSON().then(word => {
word;
localStorage.setItem("wor", word)
});
console.log("Word ", localStorage.getItem("wor"));
localStorage.setItem("Won", "false");
wordle = localStorage.getItem("wor").toUpperCase();
console.log("WordUPSCALE ", wordle);
checkLastWinDates();
localStorage.setItem("gamePlayed", "false");
location.reload();
}
In this way it refreshes the site before it could fetch, so the word remains the same when i set the clock to a next day. If I do the reset with a delay, it works quite unreliably. I added 2000 minisec delay and if the backend is a bit slower then usual it doesn’t refresh the word if its quicker it does. So I would need a bulletproof method to make sure the word always refresh before the page.
You should put the reload inside the then block, so it will be executed after fetching.
function runOncePerDay() {
if (!hasOneDayPassed()) return false;
fetchWordJSON().then(word => {
word;
localStorage.setItem("wor", word);
console.log("Word ", localStorage.getItem("wor"));
localStorage.setItem("Won", "false");
wordle = localStorage.getItem("wor").toUpperCase();
console.log("WordUPSCALE ", wordle);
checkLastWinDates();
localStorage.setItem("gamePlayed", "false");
location.reload();
});
}
Promises run asynchronously. In your code here:
function runOncePerDay() {
...
fetchWordJSON().then(word => {
word;
localStorage.setItem("wor", word)
});
...
location.reload();
}
The callback passed to .then() is waiting on the fetch, but the execution in the rest of the runOncePerDay function continues, and location.reload() gets called, thus reloading the page before the fetch has complete. (It's a race condition)
To fix this, put the location.reload() after the logic in the .then() callback. So everything in your localStorage gets set before the reload happens.

how to use native javascript methods in Vue created() hook? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
i am creating simple Vue.js application i am using Vue cli 3, I want to use native DOM method, to watch scroll behavior, Everything works fine, but the problem occurs when i am changing router view, and then console throws error Uncaught TypeError: Cannot read property of undefined what i am doing wrong?
created() {
/* contorl slider scroll height and give navbar fixed positiom */
window.addEventListener("scroll", ()=>{
var firstbox = document.getElementById("sliderBox");
if (window.scrollY >= firstbox.scrollHeight) {
this.isVisiable = true
} else {
this.isVisiable = false
}
});
},
To be a honest, I could not understand exactly what your problem is, but i think you are using addEventListener not right way, if you want to use it in created() hook also you need to destroy it after route changed, in Vue2 you can use destroyed() hook, but in Vue3 you can use unmounted(), hope this will help you
methods:{
yourFunction() {
var firstbox = document.getElementById("sliderBox");
if (window.scrollY >= firstbox.scrollHeight) {
//do something
} else {
//do something
}
}
}
created() {
window.addEventListener("scroll", this.yourFunction);
},
unmounted(){
window.removeEventListener("scroll", this.yourFunction)
}
.

Call function in itself in callback [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
i am not quite sure that Title related to my problem, so sorry.
I have asynchronous function that call callback function. So the main idea is I want to call function "dodo" each time after "asyncFunc" is done.
Are there some patterns for that? Are there issues releated to memory leak ?
var can = true;
function dodo() {
if(can)
{
can = false;
asyncFunc(function(data) {
doSmth();
can = true;
});
}
}
setInterval(dodo, 0);
The main idea is I want to call function "dodo" each time after "asyncFunc" is done.
So just call it there:
function dodoForever() {
asyncFunc(function(data) {
doSmth();
dodoForever(); // <==
});
}
dodoForever();
You don't need a global can state and setInterval.
You can just call it. Like so.
var can = true;
function dodo() {
if(can)
{
can = false;
asyncFunc(function(data) {
dodo(); // this will run `dodo` function again.
doSmth();
can = true;
});
}
}
setInterval(dodo, 0);
As the comments mention this will blow the stack up. You have dodo running every 0ms. This will basically call dodo a TON of times and that is basically all your program will be doing. I can't think of a use case where this would be necessary and it probably won't fair so well in terms of performance.
Really think about why you are trying to run it like that and what the end goal is.

Why jQuery event loop is interrupted on exception [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
After a weird behaviour of our application (using strophe XMPP and jQuery), we have discovered that the jQuery event loop is synchronous and does not catch exception.
It means that if the first event handler raises an exception, the second one is never called.
$(document).ready(function() {
$(document).bind('foo', onFoo);
$(document).bind('bar', onBar);
$(document).trigger('foo');
$(document).trigger('bar');
});
function onFoo(e) {
console.log('listener onFoo');
throw 'fail onFoo';
}
function onBar(e) {
console.log('listener onBar'); // not called
}
We expected to see two outputs, but the second one : "listener onBar" was never displayed.
See JQuery code, in "trigger" function, there is no try/catch pattern during the loop of the handlers.
while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
event.type = i > 1 ?
bubbleType :
special.bindType || type;
// jQuery handler
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
if ( handle ) {
handle.apply( cur, data );
}
... (line 4998 in JQuery 1.10.2)
We have been surprised by this implementation.
In pure JavaScript, all the handlers are called even if one of them crashed: http://jsfiddle.net/bamthomas/kgS7A/2/.
Does someone know why jQuery team does not allow the execution of the next handler even if the previous one crashed ? Why exceptions are not caught?
Why didn't they use JavaScript event handler?
This happens because of this loop taken from the .dispatch source:
while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
// Triggered event must either 1) have no namespace, or
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
if (!event.namespace_re || event.namespace_re.test(handleObj.namespace)) {
event.handleObj = handleObj;
event.data = handleObj.data;
ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler)
.apply(matched.elem, args);
if (ret !== undefined) {
if ((event.result = ret) === false) {
event.preventDefault();
event.stopPropagation();
}
}
}
As you can see, there is no try/catch around .apply.
That's the way it has been for years and years and years.
Even if they wanted, changing it now will break too much existing code. Remember, lots of things in jQuery that seem arbitrary now were born in another time.
You can of course 'fix' this in your own code (wrapping it in a try/catch with error message), but you'll surprise pretty much everyone else.

Cancel event when delay was not met? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to be able to cancel an event based on the amount of time an element is hovered on. Say when I set the delay to 500ms, when the element is being hovered on for less than that, an event should be cancelled, otherwise it is fired. The delay() and setTimeout() function seem incapable of doing that.
You can try something like this instead of using jQuery delay method.
Working demo
var timeoutId = null;
$("selector").hover(function(){
if(timeoutId)
clearTimeout(timeoutId);
timeoutId = setTimeout(function(){
alert("do your stuff here");
}, 5000);
}, function(){
clearTimeout(timeoutId);
});
Someone might come up with something cleaner but the code below will be able to handle what you are asking. It requires 500 milliseconds to pass before the code inside the event can be triggered again. Could probably clean it up so that timer/delayMet aren't potentially global variables.
I'm using $('a').click as an example selector and event.
var timer,
delayMet = true;
$('a').click(function () {
if(delayMet === true) {
// your code here
}
else {
delayMet = false;
setTimeout(function () {
delayMet = true;
}, 500);
}
});
You can cancel setTimeout() by doing the following.
var timer = setTimeout(function(){...},5000);
...
clearTimeout(timer);
From jQuery .delay() docs:
The .delay() method is best for delaying between queued jQuery
effects. Because it is limited—it doesn't, for example, offer a way to
cancel the delay—.delay() is not a replacement for JavaScript's native
setTimeout function, which may be more appropriate for certain use
cases.
Not sure if that is what you mean though.

Categories

Resources