For some reason, document ready and all associated functions fire multiple times (usually twice, but sometimes even endlessly) ever since I've added the load function to a control within document ready (meant to load content into a DIV when the current document is already loaded).
These are the scripts I'm using in my head tag and these are included in all pages (the page loaded into another, would have the same script, which is what I suspect causing the problem):
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<script src="scripts/mainscript.js"></script>
mainscript.js code:
var counter = 1;
var hasLoaded = false;
$(document).ready(function () {
if (!hasLoaded) {
hasLoaded = true;
if ($('.next-page').attr("data-loaded") == "false") {
console.log(counter + ") STARTED LOADING!");
$(this).attr("data-loaded", "true");
$('.next-page').load($('.next-page').attr("data-link"), function () {
counter++;
$(this).attr("data-loaded", "true");
console.log(counter + ") FINISHED LOADING!");
});
}
}
$('.tbDropDownBig li').click(function (e) {
$(this).parent().parent().find('input').val($(this).text());
$(this).parent().fadeOut(100);
});
});
OUTPUT from above console.log commands:
1) STARTED LOADING!
2) FINISHED LOADING!
1) STARTED LOADING!
2) FINISHED LOADING!
2) FINISHED LOADING!
Direction to detecting the problem:
The page loaded into "next-page" runs the same script, when loaded, of document load (because ALL pages have this script).
So it loads the data again. That is why I put the data-loaded attribute, but it hasn't helped.
Solved by stopping use of "ready", instead, binded "load" event to window like this:
function LoadNextPage() {
if (!hasLoaded) {
$('.next-page').load($('.next-page').attr("data-link"), function () {
$(this).attr("data-loaded", "true");
hasLoaded = true;
});
}
}
$(window).bind("load", function() {
LoadNextPage();
});
Related
I have below code that I have written in JavaScript and the script is referenced on the webpage. When the page loads, a call JavaScript happens and the logic's action should be rendered on the webpage.
Right now the script is firing on the webpage, but the action is not getting rendered on the webpage. However, if I execute the script on page console, changes happen.
<script>
function bannerLoad() {
var delayAddOn = setInterval(function() {
if ($(".add-ons").hasClass("current")) {
if ($('.addons-sidebar.clearfix img').length < 1) {
$(".addons-container :last").append($('<img>', {
class: 'img-responsive',
src: 'https://www.abc.in/content/dam/abc/6e-website/banner/target/2018/06/abc.png'
}));
}
clearInterval(delayAddOn);
}
}, 100);
};
window.onload = function() {
bannerLoad();
};
window.onclick = function() {
bannerLoad();
};
</script>
Can anyone check if there is any issue?
You need to call the script when the page is fully loaded, else the function will be called and can't find the DOM elements.
You should wrap your code inside the ready function:
<script>
//OPEN THE READY FUNCTION
$(function(){
bannerLoad(); //Call of your function when the page is fully loaded
$(window).click(bannerLoad);
});
//CLOSE THE READY FUNCTION
function bannerLoad() {
var delayAddOn = setInterval(function()
{
if($(".add-ons").hasClass("current"))
{
if($('.addons-sidebar.clearfix img').length < 1)
{
$(".addons-container :last").append($('<img>',{class:'img-responsive',src:'https://www.abc.in/content/dam/abc/6e-website/banner/target/2018/06/abc.png'}));
}
clearInterval(delayAddOn);
}
}, 100);
};
</script>
A page can't be manipulated safely until the document is "ready." jQuery detects this state of readiness for you. Code included inside $( document ).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute. Code included inside $( window ).on( "load", function() { ... }) will run once the entire page , not just the DOM, is ready.
// A $( document ).ready() block.
$( document ).ready(function() {
console.log( "ready!" );
bannerLoad();
$(window).click(bannerLoad);
});
function bannerLoad() {
if($(".add-ons").hasClass("current"))
{
if($('.addons-sidebar.clearfix img').length < 1)
{
$(".addons-container :last").append($('<img>',{class:'img-responsive',src:'https://www.abc.in/content/dam/abc/6e-website/banner/target/2018/06/abc.png'}));
}
clearInterval(delayAddOn);
}
}, 100);
};
Your script has some little issues. I will try to evaluate them.
As bannerLoad is a function you don't need a ; at the end. Not an issue, just a hint.
As told before, bannerLoad is a function. So why would you wrap the function again in a function for your events? Just pass the function name directly, like window.click = bannerLoad;. Note that there are no bracers at the end, you just pass the name.
You function will always create a new delayAddOn variable with a new interval. So every time you click, another interval will be started and run in background. If you will do it like this, you need to put the variable on the outside of your function, to keep only one interval running at a time.
There is nothing wrong with using onload instead of a ready state from jQuery. But this belongs to you page setup and what you do. It would be more safe to rely on a ready state here, as told by others before. Because you already have a function, you could use it directly by $(bannerLoad);.
var delayAddOn;
function bannerLoad() {
delayAddOn = setInterval(function() {
if ($('.add-ons').hasClass('current')) {
if ($('.addons-sidebar.clearfix img').length < 1) {
$('.addons-container :last').append($('<img>', {
class: 'img-responsive',
src: 'https://www.abc.in/content/dam/abc/6e-website/banner/target/2018/06/abc.png'
}));
}
clearInterval(delayAddOn);
}
}, 100);
}
$(bannerLoad);
window.onclick = bannerLoad;
I would like to execute a function after a redirection on my site. Here is my code:
$('a.filter-redirect').on('click', function(){
window.location.replace('/technos/');
filter();
});
And here is my function "filter":
$('a.filter-tech').on('click', function filter(){
var tag = $(this).attr('rel');
var val_input = $('#tag').val();
if(tag === val_input){
$('#tag').val('');
$('#form').submit();
}
if(val_input){
$('#tag').val(val_input + ',' + tag)
}
$('#tag').val(tag);
$('#form').submit();
return false;
});
I am not an expert in JS and jQuery and the code may be wrong. My function works, but not after the redirection.
when you redirect to a new page the scripts on the previous page are no more executed. So you have to call this function as soon as the new page is loaded e.g. on $(window).load() or $(document).ready() not on an click in previous page.
$(document).ready(function(){
var tag = $(this).attr('rel');
var val_input = $('#tag').val();
if(tag === val_input){
$('#tag').val('');
$('#form').submit();
}
if(val_input){
$('#tag').val(val_input + ',' + tag)
}
$('#tag').val(tag);
$('#form').submit();
return false;
})
When you redirect your page location changes, which means that a new page is loaded and the old is gone.
To do some action in the new page you have to add it in that page (for example in the body on load or in a script tag)
When you go to the new page, keep all your required code inside $(document).ready() or window.load()
Somthing like this
function runOnPageLoad() {
alert('Hey There');
}
window.onload = runOnPageLoad;
Or in jquery as
$(document).ready ( function(){
alert('Hey There');
});
Hope it helps
How to enable chrome extension without clicking it.
I need to perform a certain function from my extension every time i reload a page(no clicking)
is there a way to do it.
My code which contains the on click method
chrome.extension.onMessage.addListener(function(request, sender) {
if (request.action == "getSource") {
message.innerText = request.source;
}
});
function onWindowLoad() {
var message = document.querySelector('#message');
chrome.tabs.executeScript(null, {
file: "getPagesSource.js"
}, function() {
// If you try and inject into an extensions page or the webstore/NTP you'll get an error
if (chrome.extension.lastError) {
message.innerText = 'There was an error injecting script : \n' + chrome.extension.lastError.message;
}
});
}
window.onload = onWindowLoad;
and
chrome.extension.sendMessage({
action: "getSource",
source: started(document)
});
To include jQuery:
<head>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
/*all your normal JavaScript (or include as link)*/
</script>
</head>
Using only pure JavaScript you can do this with:
window.onload = function(){/*your JavaScript code*/};
only the code within that function will be immediately executed.
In jQuery you can wrap the code you want executed upon loading of page inside of $(document).ready(function(){, e.g.
$(document).ready(function(){
/*code goes here*/
});
$(document).ready() checks for when a page is loaded enough to have functionality.
I want load some HTML document by AJAX, but I want to show it when all images in this document are loded.
$('.about').click(function () {
$(".back").load('Tour.html', function () {
$(".back").show();
});
});
".back" should be visible when all images in Tour.html are loaded, when is triggered a success event??
$(".back").load('Tour.html', function (html) {
var $imgs = $(html).find('img');
var len = $imgs.length, loaded = 0;
$imgs.one('load', function() {
loaded++;
if (loaded == len) {
$(".back").show();
}
})
.each(function () { if (this.complete) { $(this).trigger('load'); });
});
This requires at least one <img> in the returned html.
What I would suggest is to use an iframe instead. Here is some sample code in plain JavaScript:
var ifr=document.createElement("iframe");
ifr.style.display="none";
document.body.appendChild(ifr);
ifr.onload=function() {
// Do what you want with Tour.html loaded in the iframe
};
ifr.src="Tour.html";
ImagesLoaded is what you are looking for.
Place all code (ajax request in this case), when the images specified are loaded.
The plugin specifies why you cannot use load() on cached images
I'm doing an application with Phonegap and I'm using a self-built slide transition to change the pages.
It works like this:
Every page is a div with 100% height and width, so if I change the Page, I set the next div right to the currently active and slide both to the left side.
Now to the Problem: the sliding works fine, but it's executed before the content of the right div is completely loaded. So the right div slides in empty, and only after a few hundred miliseconds the content will appear.
I tried it with document.ready, but as I've read this event is only executed the first time the DOM is loaded.
Does anybody know how I can wait for the DOM to be completely rendered again after I've manipulated the DOM with Javascript?
In your case, you can pick one element in the content of the next div and keep checking it with $(...).length. If the value is > 0, the DOM is loaded and you can change the page.
You may want to try this function:
Function.prototype.deferUntil = function(condition, timeLimit) {
var ret = condition();
if (ret) {
this(ret);
return null;
}
var self = this, interval = null, time = ( + new Date());
interval = setInterval(function() {
ret = condition();
if (!ret) {
if (timeLimit && (new Date() - time) >= timeLimit) {
// Nothing
} else {
return;
}
}
interval && clearInterval(interval);
self(ret);
}, 20);
return interval;
};
Usage:
(function() {
console.log('Next page loaded');
}).deferUntil(function() {
return $('#nextDiv').length > 0;
}, 3000);
The above example will check the div that has id="nextDiv" in every 20ms (not longer than 3 seconds). When the div is loaded, it will show 'Next page loaded' in the console.
You can try on this fiddle
There is a DOMNodeInserted event that is supposed to work like document.ready but for individual DOM nodes. But it is deprecated and has lots of issues. StackOverflow users found a good alternative to it that works quite well in all mobile browsers: Alternative to DOMNodeInserted
Here is a function that will trigger a callback once all images matching a jquery selector have finished loading
Js Fiddle Sample
//css
input {width: 420px;}
//html
<div id="container"></div>
<input type="text" value="http://goo.gl/31Vs" id="img1">
<br><input type="text" value="http://wall.alafoto.com/wp-content/uploads/2010/11/Fractal-Art-Wallpapers-09.jpg" id="img2">
<br><input type="text" value="http://pepinemom.p.e.pic.centerblog.net/ssg8hv4s.jpg" id="img3">
<br><input type="button" value="Load images" name="loadImages" id="btn">
<div id="message"></div>
//javascript
//Call a function after matching images have finished loading
function imagesLoadedEvent(selector, callback) {
var This = this;
this.images = $(selector);
this.nrImagesToLoad = this.images.length;
this.nrImagesLoaded = 0;
//check if images have already been cached and loaded
$.each(this.images, function (key, img) {
if (img.complete) {
This.nrImagesLoaded++;
}
if (This.nrImagesToLoad == This.nrImagesLoaded) {
callback(This.images);
}
});
this.images.load(function (evt) {
This.nrImagesLoaded++;
if (This.nrImagesToLoad == This.nrImagesLoaded) {
callback(This.images);
}
});
}
$("#btn").click(function () {
var c = $("#container"), evt;
c.empty();
c.append("<img src='" + $("#img1").val() + "' width=94>");
c.append("<img src='" + $("#img2").val() + "' width=94>");
c.append("<img src='" + $("#img3").val() + "' width=94>");
evt = new imagesLoadedEvent("img", allImagesLoaded);
});
function allImagesLoaded(imgs) {
//this is called when all images are loaded
$("#message").text("All images loaded");
setTimeout(function() {$("#message").text("");}, 2000);
}
You could use jQuery ajax to load the content, and on success run a function with the slide.
$("#page1").load('page2.html', function() {
//do your custom animation here
});
Althoug I'm not completely sure how you're loading the content. Is it static (Already there but just not visible?) Or is it loaded with ajax?
EDIT: You could just do a small .delay() or setTimeout with a few millisec, and then animate the sliding.
I had a similar problem making a masonry site responsive. I use window.onload which waits for all elements to complete loading before initialising masonry.js. I also placed the window.onload inside .onchange function and it fired everytime the viewport resized.
I am sure applying similar principles will solve your problem.
try once
$(window).bind('load',function(){
//code
});
Maybe you can set an event on your div.
myDiv.onafterupdate = myHandler;
function myHandler() {
// Do here what you want to do with the updated Div.
}
Does this help you?
In jquery you could use $() just after your DOM manipulation code.
$(function(){
//code that needs to be executed when DOM is ready, after manipulation
});
$() calls a function that either registers a DOM-ready callback (if a function is passed to it) or returns elements from the DOM (if a selector string or element is passed to it)
You can find more here
difference between $ and $() in jQuery
http://api.jquery.com/ready/