How can I determine when two object is loaded? - javascript

I'm loading an image
obgImage.onload = function ( imageReady = true )
document.getElementById('vimeo').onload= function() {
videoReady = true;
}
What should i use to recognize when both of these are ready?
if(videoReady == true && pageReady == true){
$('#loading').fadeOut();
}
how do i make the if statement constantly check? I have query

var videoReady = false,
imageReady = false,
_ready = function() {
if (videoReady && imageReady) {
// do your code
}
else {
// waiting for the other onload function to be called
}
};
obgImage.onload = function () {
imageReady = true;
_ready();
};
document.getElementById('vimeo').onload= function() {
videoReady = true;
_ready();
};
Using this the ready function will be called two times if both elements will fire their onload function

Related

Are PASTE events asynchronous? What is the best way to handle this? [duplicate]

I have a simple past event as
document.getElementById('paste_area').addEventListener('paste', function() {
document.getElementById('notice').innerHTML='Text was successfully pasted!';
alert('Pasted');
}, true);
A working example can be found here http://jsfiddle.net/XEQzz/
The alert and notice will appear before pasting. How can I delay the alert action to happen after paste event has been actually completed?
You could put your alert in a setTimeout.
setTimeout(function() {alert('Pasted');}, 0);
This will delay the code until after the value has updated.
Just keep in mind that this in the setTimeout callback will have a different value than that in the enclosing environment.
If you'll need a reference to the outer this, which will be the element, then reference it in a variable...
var self = this;
setTimeout(function() {alert(self.value);}, 0);
Or use .bind() (Supported in most browsers that support addEventListener. Older Safari didn't support it.)...
setTimeout(function() {alert(this.value);}.bind(this), 0);
I usually do like this to mimic an onafterpaste.
I have a special function called "onafterpaste" and I use it like this:
onpaste="onafterpaste(myFunction, this)"
As you see, it also accepts an extra parameter which will be used when myFunction is called.
See (and try it out in) the following live snippet:
function onafterpaste(f,elm) {
setTimeout(function() {f(elm)},0);
}
function myFunction(elm) {
alert('After the paste, the input has the following text:\r\n\r\n'+elm.value);
}
<p>Paste something down here:</p>
<input type="text" onpaste="onafterpaste(myFunction,this)" value="The original text">
setTimeout seems the best option and you can use something like this to generalise
// object definition
function PasteMonitor(element)
{
if(typeof element == "string")
{
this.target = document.getElementById(element);
}
else if(typeof element == "object" || typeof element == "function")
{
this.target = element;
}
if(this.target != null && this.target != undefined)
{
this.target.addEventListener('paste',this.inPaste.bind(this),false);
this.target.addEventListener('change',this.changed.bind(this),false);
}
this.oldstate = "";
}
PasteMonitor.prototype = Object.create({},{
pasted:{ value: false, enumerable: true, configurable: true, writable: true },
changed:{ value: function(evt){
//elements content is changed
if(typeof this.onChange == "function")
{
this.onChange(evt);
}
if(this.pasted)
{
if(typeof this.afterPaste == "function")
{
this.afterPaste(evt);
this.pasted = false;
}
}
}, enumerable: true, configurable: true, writable: true },
inPaste:{ value: function(evt){
var cancelPaste = false;
if(typeof this.beforePaste == "function")
{
// process pasted data
cancelPaste = this.beforePaste(evt);
}
if(cancelPaste == true)
{
evt.preventDefault();
return false;
}
this.pasted = true;
setTimeout(function(){
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
this.target.dispatchEvent(evt);
}.bind(this),0);
}, enumerable: true, configurable: true, writable: true }
})
PasteMonitor.prototype.constructor = PasteMonitor;
//PasteMonitor usage
//var element = document.getElementById('paste_area');
var msgArea = document.getElementById('message');
var myMonitor = new PasteMonitor("paste_area");
//or use and object as argument => var myMonitor = new PasteMonitor(element);
myMonitor.onChange = function(evt){
if(this.pasted)
{
//do something on paste change
msgArea.innerHTML = "onChange by paste";
this.oldstate = this.target.value;
}
//check to prevent processing change event when the element loses focus if the change is done by paste
else if(this.target.value != this.oldstate)
{
msgArea.innerHTML = "onChange by typing";
}
};
myMonitor.afterPaste = function(evt){
// do something after paste
msgArea.innerHTML = "afterPaste";
};
myMonitor.beforePaste = function(evt){
// do something before the actual paste
msgArea.innerHTML = "beforePaste";
//return true to prevent paste
return false;
};
For updating own value
$(".number").on("paste", function (e) {
var Value = e.originalEvent.clipboardData.getData('text');
var Self=this
setTimeout(function () {
if (Value != Value.replace(/[^\d\.]/g, "")) {
$(Self).val(Value.replace(/[^\d\.]/g, ""));
}
}, 0);
});
Is paste_area an input? input is also an event.
Here's a working example: https://jsfiddle.net/9shcqnxo/
document.getElementById('paste_area').addEventListener('input', function() {
let inArea = document.getElementById('paste_area').value;
document.getElementById('notice').innerHTML='Text change: ' + inArea;
alert(inArea);
});

javascript multiple functions at once

As I needed help here
#ryanpcmcquen offered great help, but as a "noob" at javascript I would like to know 2 more things
When I want to create another function how do I make it?
document.addEventListener('DOMContentLoaded', function () {
'use strict';
var unitBlock = document.querySelector('select#unit_block');
var unitRowBig = document.querySelector('select#unit_row_big');
var unitRow = document.querySelector('select#unit_row');
var unitColumn = document.querySelector('select#unit_column');
var unitSize = document.querySelector('select#unit_size');
unitBlock.addEventListener('change', function () {
if (unitBlock.value === 'A') {
unitRowBig.disabled = false;
unitRowBig[4].disabled = false;
} else {
unitRowBig.disabled = false;
unitRowBig[4].disabled = true;
}
});
unitBlock.addEventListener('change1', function () {
if ((unitRowBig.value === '1') && (unitBlock.value === 'A')) {
unitRow.disabled = false;
unitRow[8].disabled = true;
unitRow[9].disabled = true;
unitRow[10].disabled = true;
unitRow[11].disabled = true;
unitRow[12].disabled = true;
}
});
});
Because it doesn't seems to work my way.
No need to add a new event, besides change1 is not a valid event, you can find a list of events here:
https://developer.mozilla.org/en-US/docs/Web/Events
Just put that conditional inside the original event handler:
document.addEventListener('DOMContentLoaded', function () {
'use strict';
var unitBlock = document.querySelector('select#unit_block');
var unitRowBig = document.querySelector('select#unit_row_big');
var unitRow = document.querySelector('select#unit_row');
var unitColumn = document.querySelector('select#unit_column');
var unitSize = document.querySelector('select#unit_size');
unitBlock.addEventListener('change', function () {
// You may want to comment out all of this section:
if (unitBlock.value === 'A') {
unitRowBig.disabled = false;
unitRowBig[4].disabled = false;
} else {
unitRowBig.disabled = false;
unitRowBig[4].disabled = true;
}
// Down to here.
// Here's your code!
if ((unitRowBig.value === '1') && (unitBlock.value === 'A')) {
unitRow.disabled = false;
unitRow[8].disabled = true;
unitRow[9].disabled = true;
unitRow[10].disabled = true;
unitRow[11].disabled = true;
unitRow[12].disabled = true;
// Including an antithetical clause,
// to account for the user changing their mind.
} else {
unitRow.disabled = true;
unitRow[8].disabled = false;
unitRow[9].disabled = false;
unitRow[10].disabled = false;
unitRow[11].disabled = false;
unitRow[12].disabled = false;
}
});
});
Note that I also included the opposite disabled conditions in an else clause, in case the user makes one choice, and then changes to another.
In case you really need two separate functions (what is not the case here), just do it like this:
unitBlock.addEventListener('change', function () {
console.log('First event listener')
});
unitBlock.addEventListener('change', function () {
console.log('Second event listener')
});
document.addEventListener stores all the functions you sent to him, so when the change event will be fired, it will execute all of them, in the order you passed them to it.
In short, when the change event is fired, you will have:
> "First event listener"
> "Second event listener"
I hope this helped you!

Preventing Jquery .click toggle function from running over and over with excess clicking

Im building a .clicktoggle function in jQuery and for the life of me i can't get a .stop like effect on it, basically i don't want it to play over and over if mash clicked.
I want it to be applied the the function so its self contained, that's where im stuck.
JS fiddle link
(function($) {
$.fn.clickToggle = function(func1, func2) {
var funcs = [func1, func2];
this.data('toggleclicked', 0);
this.click(function() {
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 2;
});
return this;
};
}(jQuery));
$('div').clickToggle(function() {
$('.testsubject').fadeOut(500);
}, function() {
$('.testsubject').fadeIn(500);
});
<div class="clickme">click me fast</div>
<div class="testsubject">how do i stop it playing over and over if you click alot</div>
Toggle .click seems like something alot of people would use so i thought it might be useful to ask it here
By adding a check to a boolean variable fadeInProgress, you can choose to only queue the animation if fadeInProgress is false. It then sets the value to true and executes the animation. When the animation is completed, set the value to false.
var fadeInProgress = false;
$('div').clickToggle(function() {
if (!fadeInProgress) {
fadeInProgress = true;
$('.testsubject').fadeOut(700, function(){fadeInProgress = false;});
}
}, function() {
if (!fadeInProgress) {
fadeInProgress = true;
$('.testsubject').fadeIn(700, function(){fadeInProgress = false;});
}
});
var clicked = false;
var doing = false;
$(".clickme").click(function(e) {
if (doing) {
return;
} else {
doing = true;
}
doing = true;
clicked = !clicked;
if (clicked) {
$('.testsubject').fadeOut(700, function() {
doing = false
});
} else {
$('.testsubject').fadeIn(700, function() {
doing = false;
});
}
});
This example is a simple toggle which only allows you to click when it is not doing anything. I explained on IRC, but as an example here, the function only runs when doing is set to false, which only happens when it's set after fadeIn() or fadeOut's callback function thingymajigger.

A script is executed/not executed due to when jQuery is loaded - Why?

This is a problem I have. Try this code:
if (typeof jQuery == 'undefined') {
function getScript(url, success) {
var script = document.createElement('script');
script.src = url;
var head = document.getElementsByTagName('head')[0];
done = false;
script.onload = script.onreadystatechange = function () {
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
done = true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
};
};
head.appendChild(script);
};
getScript('http://code.jquery.com/jquery-1.11.2.min.js', function () {
if (typeof jQuery !== 'undefined') {
jQuery(document).ready(function ($) {
MyFunction($);
});
}
});
} else {
jQuery(document).ready(function ($) {
MyFunction($);
});
}
function MyFunction($) {
$.getJSON("http://archiesocial.progettiarchimede.it/widget_privacy/test.aspx?asd=1&callback=?", function (d) {
}).done(function(d) {
JsonToHtml(d);
});
}
function JsonToHtml(html) {
var items = [];
$.each(html, function (key, val) {
items.push(val);
});
$('body').prepend(items.join(''));
}
you will notice that my code check if jQuery is loaded. If not, it loads a version from external source; than retrieve a JSON, parse it and "execute it".
As you can see, the script loaded inside the body it is not loaded at all (this is my problem).
Now, try to choose a version/library of jQuery in the fiddle (1.8.3 is ok) and press play: you will see the script/button render as well: the script is executed!!!
Why loading jQuery first (here) render the script, and load jQuery later won't execute the script? Can you help me?
I think your best bet is to force onload event to be refired if it is already fired because as you are loading jQuery (if undefined), this event is already fired. This is a workaround:
function JsonToHtml(html) {
var items = [];
$.each(html, function (key, val) {
items.push(val);
});
$('body').prepend(items.join(''));
if (document.readyState === 'complete') { // check if document is complete
var evt = document.createEvent('Event');
evt.initEvent('load', false, false);
window.dispatchEvent(evt); // then redispatch onload event
}
}
-DEMO-
I think the problem is the scope. The functions MyFunction() and JsonToHtml() are out of the scope. (Remember you are working with async functions like getJSON) Maybe my explanation are wrong, but the code works. :P
With this code you have no problem.
function _test(){}
_test.prototype = {
hasjQuery: function(){
if(typeof window.jQuery !='undefined' && !_test.prototype.otherLibrary() ) {
return true;
}else{
return false;
}
},
otherLibrary: function(){
if (typeof document.$ == 'function') {
return true;
}else{
return false;
}
},
inyectjQuery: function(url, success){
var script = document.createElement('script');
script.src = url;
script.id = "delete";
done = false;
script.onload = script.onreadystatechange = function() {
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
done = true;
success();
script.onload = script.onreadystatechange = null
}
};
document.getElementsByTagName('head')[0].appendChild(script)
},
myFunction: function(){
urljQuery = 'http://code.jquery.com/jquery-latest.min.js';
if(_test.prototype.hasjQuery()){
jQuery.getJSON("http://archiesocial.progettiarchimede.it/widget_privacy/test.aspx?asd=1&callback=?",
function (d) {
_test.prototype.JsonToHtml(d);
}).done(function() {
console.log("Success getJSON action");
});
}else{
_test.prototype.inyectjQuery(urljQuery, function(){
if (typeof window.jQuery == 'undefined') {
console.log("unable to load jQuery");
}else{
jQuery.getJSON("http://archiesocial.progettiarchimede.it/widget_privacy/test.aspx?asd=1&callback=?",
function (d) {
_test.prototype.JsonToHtml(d);
}).done(function() {
console.log("Success getJSON action");
});
}
});
}
},
JsonToHtml: function(html){
var items = [];
jQuery.each(html, function (key, val) {
items.push(val);
});
jQuery('body').prepend(items.join(''));
}
}
test = new _test();
test.myFunction();

loading my script using getScript

at first I'm loading all my js script in my header and it's all working properly. But I have one js file that need to be loaded inline/ load it in a certain page only.
this is the js file that I need to load
var myScroll,pullDownEl, pullDownOffset, generatedCount = 0;
function pullDownAction () {
setTimeout(function () {
var el, li, i;
el = document.getElementById('newlist');
if ( el.hasChildNodes() ) {
while ( el.childNodes.length >= 1 ) {
el.removeChild( el.firstChild );
}
}
for (i=0; i<6; i++) {
li = document.createElement('li');
li.innerText = 'Generated row ' + (++generatedCount);
el.insertBefore(li, el.childNodes[0]);
}
myScroll.refresh();
}, 1000);
}
function loaded() {
pullDownEl = document.getElementById('pullDown');
pullDownOffset = pullDownEl.offsetHeight;
myScroll = new iScroll('wrapper', {
//hideScrollbar: false,
//hScrollbar: false, vScrollbar: false, vScroll: false,
useTransition: true,
topOffset: pullDownOffset,
onRefresh: function () {
if (pullDownEl.className.match('loading')) {
pullDownEl.className = '';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
$('#pullDown').css('display', 'inherit');
$('#pullDown').css('display', 'none');
$('#thelist').css('display', 'none');
$('#newlist').css('display', 'inherit');
}
},
onScrollMove: function () {
if (this.y > 5 && !pullDownEl.className.match('flip')) {
pullDownEl.className = 'flip';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Release to refresh...';
$('#pullDown').css('display', 'inherit');
this.minScrollY = 0;
} else if (this.y < 5 && pullDownEl.className.match('flip')) {
pullDownEl.className = '';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
$('#pullDown').css('display', 'inherit');
this.minScrollY = -pullDownOffset;
}
},
onScrollEnd: function () {
if (pullDownEl.className.match('flip')) {
pullDownEl.className = 'loading';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading...';
pullDownAction();
}
}
});
setTimeout(function () { document.getElementById('wrapper').style.left = '0'; }, 800);
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
loading it with my other script in my header it works but now I'm using the jquery getScript. It loads the script (using firebug) but when I tried calling the functions inside my js file it give me a two errors
Cannot read property 'offsetHeight' of null
Cannot call method 'refresh' of undefined
This is how I call my js script using getScript
$(document).ready(function() {
$('.email').click(function (){
$.getScript("assets/js/scroll.js",function() {
pullDownAction();
loaded();
});
});
});
Help anyone
I know this may suggest more work than you want to do, but have you tried doing namespacing? I do not know if this works 100% (as i am not sure of the reasoning why that is not working for you), but have you tried this?
(function( PullDown, $, undefined ) {
//Private variables and this is a great way for minification, you will get the most out of it
var myScroll,pullDownEl, pullDownOffset, generatedCount = 0;
function pullDownAction () {
//... your stuff here
}
function loaded() {
//... more your stuff here
}
}(window.PullDown = window.PullDown || {}, jQuery) // avoids name space collision w/ jQuery
Now do the same things, but with this edit.
$(document).ready(function() {
$('.email').click(function (){
$.getScript("assets/js/scroll.js",function() {
window.PullDown.pullDownAction();
window.PullDown.loaded();
});
});
});
If i am not mistaken, or have bad copy and paste skills, this should work out just great!

Categories

Resources