how to judge imgs is all loaded - javascript

I have a project to know the imgs' height when the document is loading,but at first i got the height is zero So is there any tips to know whether the imgs is already loaded? I tried to use $.deferred inside jQuery; here is my code:
$(function() {
var imgdefereds = [];
$('img').each(function() {
var dfd = $.Deferred();
$(this).bind('load', function() {
dfd.resolve();
}).bind('error', function() {
//error callback
})
if (this.complete) {
setTimeout(function() {
dfd.resolve();
}, 1000);
}
imgdefereds.push(dfd.promise());
})
$.when.apply(null, imgdefereds).done(function() {
console.log('complete');
});
})
It didn't work. How can I fix it?

Try this:
$("img").one("load", function() {
// do stuff
}).each(function() {
if(this.complete) {
// do stuff
}
});

Related

Disable button until function is done

I am trying to disable the button until the code is successfully executed. Unfortunately, the button is activated too early, the function is still running. How can I prevent this?
$("#myButton").click(function() {
$(this).prop("disabled", true)
doSomethingFunction()
$(this).prop("disabled", false)
});
Edit:
Thank you all for your help. I have adjusted my code. Can you do it this way or are there better ways?
class TestClass
{
static doSomethingFunction() {
return new Promise(function (resolve, reject) {
setTimeout(function () { console.log("function is done"); resolve(self); }, 5000);
})
}
}
$("#myButton").click(function() {
$(this).prop("disabled", true)
TestClass.doSomethingFunction().then(r => $(this).prop("disabled", false))
});
The second solution does not work for me, because "completely done" is output before "function is done"
class TestClass
{
static doSomethingFunction(callback) {
setTimeout(function () { console.log("function is done");}, 2000);
if(callback !== undefined){
callback();
}
}
}
$("#myButton").click(function() {
$(this).prop("disabled", true)
TestClass.doSomethingFunction(function(){
console.log("completely done")
});
});
What am I doing wrong?
Consider the following.
var myData;
function doSomethingFunction(callback){
$.get("someplace.php", function(data){
myData = data;
if(callback !== undefined){
callback();
}
});
}
$("#myButton").click(function() {
var $self = $(this);
$self.prop("disabled", true);
doSomethingFunction(function(){
console.log(myData);
$self.prop("disabled", false);
});
});
This allows you to pass in code to run once the function is complete. In this example, maybe it's getting data from the server. This may take almost no time, or maybe the report takes 1.2 seconds to generate. Either way it will not be run until the AJAX is successful.
Update
Here is an example, based on the following: How do I use jQuery promise/deffered in a custom function?
$(function() {
function doSomething() {
var deferred = new $.Deferred();
setTimeout(function() {
deferred.resolve(10);
}, 10 * 1000);
return deferred;
}
$("button").click(function() {
var $self = $(this);
console.log("Disabled");
$self.prop("disabled", true);
doSomething().then(function() {
$self.prop("disabled", false);
console.log("Enabled");
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Start</button>
This will run for 10 seconds and then enable the button. Applying it to your example.
class TestClass {
static doSomethingFunction() {
var deferred = new $.Deferred();
setTimeout(function() {
deferred.resolve(10);
}, 5 * 1000);
return deferred;
}
}
$("#myButton").click(function() {
var $self = $(this);
$self.prop("disabled", true);
TestClass.doSomethingFunction().then(r => $self.prop("disabled", false));
});

jQuery plugins functions overwrite

I have implemented several jQuery plugins for my current project.
Since some plugins have functions with the same name, the one called in the last one defined.
Here is the definition of my first plugin:
$(function($)
{
$.fn.initPlugin1 = function(parameters)
{
var defaultParameters = {};
$(this).data('parameters', $.extend(defaultParameters, parameters));
return $(this);
};
$.fn.function1 = function(){ console.log('Function 1.'); };
$.fn.callFunction = function(){ $(this).function1(); };
});
And here is the definition of my second plugin:
$(function($)
{
$.fn.initPlugin2 = function(parameters)
{
var defaultParameters = {};
$(this).data('parameters', $.extend(defaultParameters, parameters));
return $(this);
};
$.fn.function2 = function(){ console.log('Function 2.'); };
$.fn.callFunction = function(){ $(this).function2(); };
});
I have also this scenario :
$("#div1").initPlugin1().callFunction();
$("#div2").initPlugin2().callFunction();
For this specific scenario the consoles shows: Function 2. Function 2.
In fact, since the callFunction() is also defined in the second plugin, this is the one used.
I would like some advise on what is the best way to solve this problem.
Is it possible to create a thing similiar to a namespace ?
Thank to #syms answer, I have created the following example.
Plugin1:
$(function($) {
$.fn.initPlugin1 = function() {
console.log('Initialized Plugin1');
return $(this);
};
$.fn.initPlugin1.testFunction = function() {
$(this).append('Function 1.');
};
});
Plugin2:
$(function($) {
$.fn.initPlugin2 = function() {
console.log('Initialized Plugin2');
return $(this);
};
$.fn.initPlugin2.testFunction = function() {
$(this).append('Function 2.');
};
});
Main:
(function($)
{
$(document).ready(
function()
{
$("#div1").initPlugin1(); //Run correctly
$("#div2").initPlugin2(); //Run correctly
$("#div1").initPlugin1.testFunction(); //Fail
$("#div2").initPlugin2.testFunction(); //Fail
});
})(jQuery);
When I run my code, I got the following error: Cannot read property 'createDocumentFragment' of null.
Apparently, the this object is corrupted.
you can try this,
$(function($) {
$.fn.initPlugin1 = function() {
console.log('Initialized Plugin1');
return $(this);
};
});
$(function($) {
$.fn.initPlugin2 = function() {
console.log('Initialized Plugin2');
return $(this);
};
$.fn.callFunction = function(param) {
$(this).append(param);
};
});
(function($) {
$(document).ready(
function() {
$("#div1").initPlugin1(); //Run correctly
$("#div2").initPlugin2(); //Run correctly
$("#div1").initPlugin1().callFunction('function1');
$("#div2").initPlugin2().callFunction('function2');
});
})(jQuery);

Jquery functions Delay shortens with each Interval

I am not sure how to ask this question. I made a jQuery function for a banner.
$(document).ready(function() {
ionanim();
setInterval(ionanim, 12000);
function ionanim() {
$(function () {
$('.ion1anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500);
});
});
$(function () {
$('.ion2anim').delay(6000).fadeIn(500, function () {
$(this).delay(5000).fadeOut(500);
});
});
};
});
Link for the full animation : http://jsfiddle.net/L8XHL/11/
But with each intervatl on the setInverval the animations go close to each other after some time they overlap each other.
Did i do anything wrong?
Intervals and animations aren't exact enough to handle the timing that you require. I'd suggest using a self-executing function instead so that it will never overlap.
Also, you are over-using the document ready handler. Please stop.
http://jsfiddle.net/L8XHL/13/
$(document).ready(function () {
ionanim();
function ionanim() {
$('.ion1anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500, function () {
$('.ion2anim').fadeIn(500, function () {
$(this).delay(5000).fadeOut(500,ionanim);
});
});
});
}
});
I would further modify this to work more like a slider so that you can add an infinite number of items without having a huge pyramid of code.
http://jsfiddle.net/L8XHL/17/
$(document).ready(function () {
$(".ionbanner .bottom div").first().siblings().hide();
anim();
function anim() {
var curr = $(".ionbanner .bottom :visible");
var next = curr.next();
if (next.length == 0) {
next = curr.siblings().first();
}
curr.delay(5000).fadeOut(500,function(){
next.fadeIn(500,anim);
});
}
});
Or you could try something like this: http://jsfiddle.net/L8XHL/16/
$(document).ready(function() {
var anim1 = function() {
$('.ion1anim').fadeIn(1000, anim1Callback);
},
anim1Callback = function() {
$('.ion1anim').fadeOut(1000, anim2);
},
anim2 = function() {
$('.ion2anim').fadeIn(1000, anim2Callback);
},
anim2Callback = function() {
$('.ion2anim').fadeOut(1000, anim1);
};
anim1();
});

Recursive function : where am I wrong here?

Code :
isDomLoaded = $(function () {
setTimeout(function () {
if (renderFinished) {
renderSocial(fotoProssima);
} else {
isDomLoaded();
}
}, 300);
});
it says isDomLoaded is not a function
Thats because it isn't a function. It is a jQuery object.
What you need might be:
isDomLoaded = function () {
setTimeout(function () {
if (renderFinished) {
renderSocial(fotoProssima);
} else {
isDomLoaded();
}
}, 300);
};
If you want to run it when the DOM is ready then do this after you declare the function:
$(window).load(isDomLoaded);
However, I think what you really need is to get rid of the isDomLoaded function and just use the following:
$(document).ready(function(){
renderSocial(fotoProssima);
});
function isDomLoaded(){
//code
//recursive call
isDomLoaded();
}

Order function in JS

I have the following code in main.js:
(function($) {
// Code goes here
$.fn.switcher=function(opts)
{
var defaults={
btn:'.info_btn', //Класс кнопки
block:'.details_info', //Класс блока, который нужно скрыть
hideifout:false, //Если true то скроект блок когда мышь его покент
classActive:'open' //Класс который ставится активной кнопке
//classNotActive:'close'
};
var options=$.extend(defaults, opts);
this.each(
function(){
var $this=$(this);
var btn=$this.find(options.btn);
var block=$this.find(options.block);
var plaing=false;
var click=function(e){
if (e.type=='mouseleave')
{
e.stopPropagation();
}
if (plaing) return;
plaing=true;
if (block.is(':visible'))
{
block.hide('blind',function(){
btn.removeClass(options.classActive);
btn.css('z-index',0);
plaing=false;
});
} else {
btn.addClass(options.classActive);
btn.css('z-index',2);
block.show('blind',function(){
plaing=false;
});
}
}
btn.click(click);
if (options.hideifout){
block.mouseleave(click);
}
}
);
}
})(jQuery);
And js code in my aspx file:
<script type="text/javascript">
$(document).ready(function () {
$('#listInfoBlock').load('/cinema/filmlist'); // load films by default
$(".title").click(function (e) {
e.preventDefault();
loadFilmList($(this));
});
$("#buttonFindFilmByName").click(function (e) {
e.preventDefault();
loadFilmList($(this));
});
// load films by criteria
function loadFilmList(id) {
$('#listInfoBlock').load('/cinema/filmlist?id=' + $(id).attr("id"));
$(".tabs").find("a").removeClass("active");
$(id).parent().addClass("active");
};
});
</script>
The function loadFilmList fills listInfoBlock.
The problem in that function in main.js executes first and there are no div called .details_info (it will be there when loadFilmList is executed)
How can I solve this problem?
Thanks.
SOLUTION:
I rewrite like that:
function loadFilmList(id) {
$('#listInfoBlock').load('/cinema/filmlist?id=' + $(id).attr("id"), function () {
$('.infoBlock').switcher();
$('div.widgets').switcher(
{
btn: '.expand',
block: '.voice_block',
hideifout: true
// classActive:'expand'
});
});
if (id !== undefined) {
$(".tabs").find("a").removeClass("active");
$(id).parent().addClass("active");
}
};
now it's work.
Thanks Nate.
The problem is that you're declaring $.fn.switcher but aren't ever calling it anywhere. I think you need to call it in two places, in a callback function on both of your .load() AJAX calls.
$('#listInfoBlock').load('/cinema/filmlist', function() { $.fn.switcher({ }); });
and
$('#listInfoBlock').load('/cinema/filmlist?id=' + $(id).attr("id"), function() { $.fn.switcher({ }); });

Categories