do something when js element is loaded , is not working - javascript

I have this Jquery function to click on an element when its ready. its an interval doing it , the following function:
MonitorAndClick(selector) {
var ele = $(selector);
if (ele.length == 0) {
var intervalid = setInterval(function () {
var ele = $(selector);
if (ele.length > 0) {
ele[0].click();
clearInterval(intervalid);
return true;
}
}, 500);
} else {
ele[0].click();
return true;
}
}
the problem is in some cases , its not working. however this is an interval , and it's checking the element to be ready every 0.5 sec, so how can it be possible ? is there any other way to check the element is ready ?
additional note:
I have an accordion. I have a function to open the accordion->open one of the items->open the tab page in detail section
this is the function :
//--reach to this point, open accordion index 2--------
ShowAccordion(2);
//----open the item with specific Id in accordion items------
setTimeout(function () {
var selector = "tr[gacategory = '/myprotection/mywills/item_" + parseInt(willId) + "]";
MonitorAndClick(selector);
}, 500);
the point is this element SHOULD be there , sometimes its not loading fast enough , and I WANT TO HAVE A WAY TO CHECK IF ITS LOADED, THEN CLICK ON THAT.
Updated code after comments
var selector = "tr[gacategory = '/myprotection/mywills/item_" + parseInt(willId) + "]";
$("#selector").ready(function () {
console.log('**********.... selector is loaded ....*****');
if (!$("#selector").hasClass('selected'))
MonitorAndClick(selector);
});
still not working.

Why do you want to rely on 0.5 seconds delay to make sure your element is present in DOM. You should be invoking this function only after your element is present in the DOM. If there is another condition that drives when this element is added to the DOM, then call this function once that condition is achieved.

You may want to try https://api.jquery.com/ready/
It seems like jquery ready function can be applied on individual elements too

Related

JQuery: Onload event on image not working

I am trying to call a function after the image loads completely in DOM.
The image structure is created dynamically on AJAX call success and the image url is also added in success using the result of API call.
Problem:
I want to call a function after the image loads completely in DOM.
To do this I have used JQuery load event.
Function which is called on load.
function carouselHeight() {
$('.home-banner-img-container').each(function() {
var $this = $(this);
var dynamicheight = $(this).parent();
var sectionInnerHeight = $this.innerHeight();
dynamicheight.css({
'height': sectionInnerHeight
});
});
}
I have tried below steps but it didn't worked
$(window).on('load', function() {
carouselHeight();
});
$(window).on('load', 'img.image-preview', function() {
carouselHeight();
});
$(document).on('load', 'img.image-preview', function() {
carouselHeight();
});
The first method $(window).on('load', function() {}) works perfectly on hard reload but on normal reload it is not able to find $('.home-banner-img-container') element which is inside of carouselHeight function.
Please help me to find a solution for this. Thank you.
I have found the solution on stack overflow where I have added the below code in ajax call complete method.
function imageLoaded() {
// function to invoke for loaded image
// decrement the counter
counter--;
if( counter === 0 ) {
// counter is 0 which means the last
// one loaded, so do something else
}
}
var images = $('img');
var counter = images.length; // initialize the counter
images.each(function() {
if( this.complete ) {
imageLoaded.call( this );
} else {
$(this).one('load', imageLoaded);
}
});

Accordion Functionality

I've put together an accordion script that works quite nicely (haven't cross-browser tested) and allows for lots of content inside each drawer to be accessed and visible on screen. A lot of times accordions open and cause issues with positioning after opening. Anyway, the code I'm using has a toggle active function and a scroll function being called on click.
function toggleActive(link){ // Set anchor to active
if ( $(link).hasClass("active") ) {
$(link).removeClass("active");
} else {
$(link).addClass("active");
};
};
function scrollToElement(selector, time, verticalOffset) { // param 1 = id, param 2 = speed
time = typeof(time) != 'undefined' ? time : 1000;
verticalOffset = typeof(verticalOffset) != 'undefined' ? verticalOffset : 0;
element = $(selector);
offset = element.offset();
offsetTop = offset.top + verticalOffset;
$('html, body').animate({scrollTop: offsetTop }, time);
}
$('#accordion a').click(function(e) {
var link = '#' + event.target.id
$(".tab-content").slideUp();
$(".tab").removeClass("active");
toggleActive(link);
$(link).next().slideToggle("fast");
setTimeout(function() {
scrollToElement($(link), 500);
}, 500);
e.preventDefault();
});
So when clicked, all of the tabs are closed and made inactive, then the targeted "drawer" is opened and made active. If for any reason you click an already "active" drawer, it runs through the script again. What I'd like to do is place an IF statement that determines if what you just clicked is already open, and then simply close that drawer. Thanks in advance. I don't know why this is causing me headaches.
JSFiddle
As I understand you need another function as below:
function isAlreadyActive(link)
{
if ( $(link).hasClass("active") ) {
$(link).removeClass("active");
return true;
} else {
return false;
};
}
And you should call that function in your click event. This function will check if the link already active, if so just deactivates it and changes as you want.
$('#accordion a').click(function(e) {
var link = '#' + event.target.id
/* if it is already active, just deactivate it and exit*/
if(isAlreadyActive(link)){
return false;
}
$(".tab-content").slideUp();
$(".tab").removeClass("active");
toggleActive(link);
$(link).next().slideToggle("fast");
setTimeout(function() {
scrollToElement($(link), 500);
}, 500);
e.preventDefault();
});
I hope this helps.

Jquery .remove() does not update DOM

I am trying to remove an element form the DOM using the .remove() jQuery method
Basically i am parsing a list and removing certain elements. Then right after, i reparse the list for some treatment for the rest of the elements.
But a simple printout of the size of the list gives me the impression that the elements to be filtered out were not removed
$list = $(".elements_list");
alert( $list.size());
$list.each(function(){
if ( $(this).data("quantity") == 0)
{
$(this).slideUp(1000,function(){
$(this).remove();
});
}
});
change_background_colors();
Right after this treatment, i call another function that has the following code in the beginning:
function change_background_colors() {
$list = $(".elements_list");
alert($list.size());
...
}
I get the same size of the list before and after removing elements...
Is there something wrong in my approach ?
Thanks!
if you call the size alert in a setTimeOut function you will see
$list = $(".elements_list");
alert($list.size());
$list.each(function () {
if ($(this).data("quantity") == 0) {
$(this).slideUp(1000, function () {
$(this).remove();
});
}
});
setTimeout(function () {
$list = $(".elements_list");
alert($list.size());
}, 2000);
JSFiddle:
https://jsfiddle.net/upkkLq2m/2/
The element is not removed until after 1000 milliseconds pass and the animation completes. Wait until then to count the elements.
edit: here's the more complicated way to delay till all animates complete:
$list = $(".elements_list");
var n = 0;
$list.each(function(){
if ( $(this).data("quantity") == 0) {
n = n + 1; // one more callback to wait for
$(this).slideUp(1000,function(){
$(this).remove();
n = n-1;
checkIfAllDone();
});
}
});
function checkIfAllDone(){
if(n===0){ // be sure that n was declared in the same scope as this function
change_background_colors();
}
}

Have a JS function *constantly* listen for clicks?

This seems like something that should be really simple. I have a few images animating on a page, but I want the user to be able to click on any one of them at any time and then go to a related page.
Problem is, evidently clicks stopped being listened for at some point if I use a loop to search through an array of clickable items. I thought having a function separate from the one that handles the animation would allow it to constantly listen no matter what the animated images were doing, but it seems once the "complete" function is called (for the "animate" function), the function that is listening for clicks (wholly separate from the animation, and using setInterval to listen for clicks) stops listening.
Oddly enough, I believe I did not have this problem when just listening for "img" instead of an array of different images.
Ideas as to what I'm doing wrong? More info needed? I tried to remove any irrelevant code below.
var links = ["#portfolio", "#animations", "#games"];
$(function() {
setInterval(function(){
for (var i=0; i<links.length; i++) {
$(links[i]).click(function(){
window.location.replace("http://www.gog.com");
});
}
}, 500);
});
$(document).ready(function() {
links.forEach(function(current){
//various vars
var link = $(current);
var footer3 = $(".footer3");
var over = true;
var randomTime = 3000*(Math.random()+1);
//dust vars
...
//image vars
var imageUrlShadow = 'images/home/non-char/shadow-pngs/shadow';
var imageUrlCharacter = 'images/home/char-pngs/';
var portfolioSrc;
var animationsSrc;
var gamesSrc;
//animate the characters
link.animate({
top: '0'
}, {
duration: randomTime,
easing: 'easeOutBounce',
step: function(now, tween) {
/*handle shadows*/
...
/*handle characters*/
if (now < -25 && over == false) {
...
} else if (now >= -25) {
...
}
$("#"+ link.data("portfolio")).attr('src', portfolioSrc);
$("#"+ link.data("animations")).attr('src', animationsSrc);
$("#"+ link.data("games")).attr('src', gamesSrc);
/*handle dust*/
var dustDoneMoving = '-50px';
var dustNotMoving = '0px';
//if link is NOT touching footer3
...
//set to "sitting" images when animation is done
complete: function() {
...
setTimeout(function() {
...
}, 1000);
}
})
})
});
var links = ["#portfolio", "#animations", "#games"];
$(function() {
$(links.join(',')).click(function(){
window.location.replace("http://www.gog.com");
});
});
One time only and listener will be attached to the image.
Consider listening via window
var links = ["#portfolio", "#animations", "#games"];
$(window).on('click', links.join(', '), function() {
// do what you wanna
});
I apologize, it turns out that, apparently, the problem was related to the z-index. There were some other divs with 0 opacity "covering up" the array divs.
Setting the z-index to 2 for the array items has fixed the matter. Again, my apologies.
I have modified your code. See, if this works now.
I have added one more array which contains some URLs. So, the intention is that on click of a particular element, its respective URL should be opened.
So, the sequence in these array will matter with respect to each other.
Also, I have made use of 'on', so that 'click' event should be handled even during animation.
var links = ["#portfolio", "#animations", "#games"];
var sites = ["http://www.gog.com", "http://www.gog1.com", "http://www.gog2.com"]; //change these to the expected URLs
$(function() {
for (var i=0; i<links.length; i++) {
$(document ).on("click",links[i],function(){
window.location.replace(sites[i]);
});
}
});

A Function to Check if the Mouse is Still Hovering an Element Every 10 Milliseconds (and run a function if it is)

I was wondering if there is a function to be run after an element (e.g. div class="myiv") is hovered and check every X milliseconds if it's still hovered, and if it is, run another function.
EDIT: This did the trick for me:
http://jsfiddle.net/z8yaB/
For most purposes in simple interfaces, you may use jquery's hover function and simply store in a boolean somewhere if the mouse is hover. And then you may use a simple setInterval loop to check every ms this state. You yet could see in the first comment this answer in the linked duplicate (edit : and now in the other answers here).
But there are cases, especially when you have objects moving "between" the mouse and your object when hover generate false alarms.
For those cases, I made this function that checks if an event is really hover an element when jquery calls my handler :
var bubbling = {};
bubbling.eventIsOver = function(event, o) {
if ((!o) || o==null) return false;
var pos = o.offset();
var ex = event.pageX;
var ey = event.pageY;
if (
ex>=pos.left
&& ex<=pos.left+o.width()
&& ey>=pos.top
&& ey<=pos.top+o.height()
) {
return true;
}
return false;
};
I use this function to check that the mouse really leaved when I received the mouseout event :
$('body').delegate(' myselector ', 'mouseenter', function(event) {
bubbling.bubbleTarget = $(this);
// store somewhere that the mouse is in the object
}).live('mouseout', function(event) {
if (bubbling.eventIsOver(event, bubbling.bubbleTarget)) return;
// store somewhere that the mouse leaved the object
});
You can use variablename = setInterval(...) to initiate a function repeatedly on mouseover, and clearInterval(variablename) to stop it on mouseout.
http://jsfiddle.net/XE8sK/
var marker;
$('#test').on('mouseover', function() {
marker = setInterval(function() {
$('#siren').show().fadeOut('slow');
}, 500);
}).on('mouseout', function() {
clearInterval(marker);
});​
jQuery has the hover() method which gives you this functionality out of the box:
$('.myiv').hover(
function () {
// the element is hovered over... do stuff
},
function () {
// the element is no longer hovered... do stuff
}
);
To check every x milliseconds if the element is still hovered and respond adjust to the following:
var x = 10; // number of milliseconds
var intervalId;
$('.myiv').hover(
function () {
// the element is hovered over... do stuff
intervalId = window.setInterval(someFunction, x);
},
function () {
// the element is no longer hovered... do stuff
window.clearInterval(intervalId);
}
);
DEMO - http://jsfiddle.net/z8yaB/
var interval = 0;
$('.myiv').hover(
function () {
interval = setInterval(function(){
console.log('still hovering');
},1000);
},
function () {
clearInterval(interval);
}
);

Categories