I need to access an element, both inside and outside of the $( document ).ready() scope.
Assume the following code:
var text__holder = $('#text__holder');
$(function() {
text__holder.text('Inside DOM ready');
/*
SOME MORE ACTION WITH ELEMENT
*/
});
var writeSomeTxt = function () {
text__holder.text('Outside DOM ready');
};
writeSomeTxt();
In this case I can't access the element inside the function. The JS is also in external .js file which is included in <head> part of the page and I cant replace it elsewhere.
My current "workaround" for this is:
var text__holder = $('#text__holder');
$(function() {
text__holder.text('Inside DOM ready');
/*
SOME MORE ACTION WITH ELEMENT
*/
});
var writeSomeTxt = function () {
$(function() {
text__holder.text('Outside DOM ready');
});
};
writeSomeTxt();
The issue is likely that you can't just this line of code:
var text__holder = $('#text__holder');
Until the DOM has been loaded. If you do, you just get an empty jQuery object because it will not find any matching DOM objects.
If you know that writeSomeTxt() won't be called until after the DOM has been loaded, then you could do this:
var text__holder;
$(function() {
text__holder = $('#text__holder');
text__holder.text('Inside DOM ready');
/*
SOME MORE ACTION WITH ELEMENT
*/
});
var writeSomeTxt = function () {
text__holder.text('Outside DOM ready');
};
// don't call this until after the DOM is loaded
// presumably based on some DOM event
writeSomeTxt();
But, really, there's no point in trying to cache a single DOM reference like that anyway so the better way to write your code would be this:
$(function() {
$('#text__holder').text('Inside DOM ready');
/*
SOME MORE ACTION WITH ELEMENT
*/
});
var writeSomeTxt = function () {
$('#text__holder').text('Outside DOM ready');
};
// don't call this until after the DOM is loaded
// presumably based on some DOM event
writeSomeTxt();
Or, if all this code is supposed to run at page initialization time, then just put it all inside of the .ready() handler.
$(function() {
var text__holder = $('#text__holder');
text__holder.text('Inside DOM ready');
/*
SOME MORE ACTION WITH ELEMENT
*/
var writeSomeTxt = function () {
text__holder.text('end of DOM ready');
};
writeSomeTxt();
});
You can declare functions and variables outside document.ready and define the variable inside as well as call function inside once variable is defined:
var text__holder;//declare undefined varible
$(function() {
text__holder = $('#text__holder');// can now define varible
text__holder.text('Inside DOM ready');
// call function now that variable is defined
writeSomeTxt();
});
var writeSomeTxt = function () {
text__holder.text('Outside DOM ready');
};
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 have a function defined as follows:
window.onload = function() {
var ids = document.getElementById("idname");
function myFunction(){
/...*use ids var in here*./
}
}
I am trying to call myFunction from button onclick in html:
<button onclick="myFunction();"></button>
But it says myFunction is not defined. I understand because this is inside window.onload. How can I fix this? I need window.onload because I need to use document.getElementById("testID") to get content.
I need window.onload because I need to use document.getElementById("testID") to get content
No, you don't need window.onload. You simply have to put the code somewhere after the element with ID testID in the document.
Example:
<div id="testID"></div>
<script>
var ids = document.getElementById("testID");
function myFunction(){
/...*use ids var in here*./
}
</script>
However, if you want to keep using window.onload, then I suggest to not use inline event handlers, but bind the handler with JS:
window.onload = function() {
var ids = document.getElementById("testID");
ids.onclick = function(event){
/...*use ids var in here*./
}
};
(that might be a good thing to do anyway).
Lastly, you can get the a reference to the element inside the event handler using this or event.target:
<div id="testID"></div>
<script>
document.getElementById("testID").onclick = function(event) {
// access element via `this` or `event.target`
};
</script>
Learn more about event handling.
You defined it within a function so it's locked to that scope. Maybe you want to define it outside of that:
function myFunction() {
var ids = document.getElementById("idname");
// ...
}
window.onload = function() {
// ...
}
As a note, this is extremely old-school JavaScript. You could clean this up considerably using something like jQuery which would look something like this:
$(function() {
// Any initialization after page load.
});
function myFunction() {
var ids = $('#idname');
// ...
}
How come this doesn't work in loading header content...
(function ($) {
var mheaderwrapper = '<div id="header"></div><div class="header-menu"></div>';
var mheadercontent = '/shop/Pages/global_header.html';
var mmenucontent = '/shop/Pages/global_megamenu.html';
var mjqueryhover = 'js/jquery.hoverIntent.minified.js';
var mjquerymenu = 'js/jquery.custom-menu.js';
$('#wrapper').prepend(mheaderwrapper);
$('#header').load(mheadercontent);
$('.header-menu').load(mmenucontent, function(){
$.getScript(mjqueryhover);
$.getScript(mjquerymenu);
});
})(jQuery);
but this does...
$.mheader = function() {
var mheaderwrapper = '<div id="header"></div><div class="header-menu"></div>';
var mheadercontent = '/shop/Pages/global_header.html';
var mmenucontent = '/shop/Pages/global_megamenu.html';
var mjqueryhover = 'js/jquery.hoverIntent.minified.js';
var mjquerymenu = 'js/jquery.custom-menu.js';
$('#wrapper').prepend(mheaderwrapper);
$('#header').load(mheadercontent);
$('.header-menu').load(mmenucontent, function(){
$.getScript(mjqueryhover);
$.getScript(mjquerymenu);
});
}
$(function() {
$.mheader();
});
This :
(function ($) {....})(jQuery);
executes immediately, and only maps jQuery to $ to make sure the dollar sign really is "jQuery" within the self executing function. It's not a "DOM ready" function.
This:
$(function() {....});
will wait until the DOM is ready before any code is executed.
You can use the second one inside the first one :
(function ($) {
$(function() {
//code here
});
})(jQuery);
to do both!
When you have a function in the <head> section like that, it is executing immediately, and is doing so before your HTML elements have started loading. Your elements #wrapper, #header, and anything with the .header-menu class do not yet exist at the time your code is executing, which is why it fails.
In the second example, using the domready event delays the firing of your code until after the DOM is ready (and your HTML elements exist), so the code works.
By the way,
$(function() {
// executes when DOM is ready
});
is just a shortcut for:
$(document).ready(function() {
// executes when DOM is ready
});
The above examples are specifically functionality provided by jQuery. Don't confuse the former with the immediately-executing function structure, which is pure JavaScript:
(function() {
// executes NOW
})();
See adeneo's answer for how to properly combine the two.
$(document).ready actually runs after the DOM is created.
Self-invoking functions run instantly if inserted into <head> section, before the DOM is constructed.
I have a block of code like so:
function doSomething() {
someVar.on("event_name", function() {
$('#elementId').click(function(e) {
doSomething();
});
});
}
// and on document ready
$(function () {
$('#anotherElemId').click(function () {
doSomething();
});
});
The problem that I'm encountering is that when I call doSomething() from anotherElemId click event(that is binded on document ready) it works as expected, but calling it recursively from elementId click doesn't work.
Any ideas? Thinking is something trivial that I'm missing.
Is someVar an actual jQuery reference to a dom element? (e.g. $('#someitem'))
The second problem is you cant put a .click event inside a function that you would like to instantiate later on. If you are trying to only allow #elementId to have a click event AFTER some previous event, try testing if a tester variable is true:
var activated = false;
$(function () {
$('#anotherElemId').click(function () {
activated = true;
});
$('#secondElemId').on("event_name", function() {
if (activated) {
// code that happens only after #anotherElemId was clicked.
}
});
});
I'm trying to create a Singleton object that deals with servicing an event listener:
var ChildParent = (function () {
var html_element = document.getElementById("quoteNum");
var row_number = 0;
return {
init: function(){
html_element["parenttype"+row_number].addEventListener("click", ChildParent.fire, false);
},
add: function(total) { //Adding a row
},
fire: function() {
alert("it fired!");
}
}
})();
However, when I call ChildParent.init(), the document-element will not get assigned to html_element, so i can't attach the listener. Oddly enough, the row_number variable is initialized to zero. Is there some sort of scoping conflict that I don't understand? When i use the step-into feature of opera's dragonfly, I can't create var assignments when in the init() function.
Make sure element with id "quoteNum" is available on the page when you are executing your script.
It may happen that you are executing the script without waiting for all the page elements to be rendered.
You may think about handling window.onload.
Update
the following change could help you fix the issue with html_element being initialized before the page is rendered.
var ChildParent = (function () {
function getElement(){
return html_element ? html_element : html_element = document.getElementById("quoteNum");
}
var html_element;
var row_number = 0;
return {
init: function(){
getElement()["parenttype"+row_number].addEventListener("click", ChildParent.fire, false);
},
add: function(total) { //Adding a row
},
fire: function() {
alert("it fired!");
}
}
})();
Is the above code executed after the element with id quoteNum exists in the DOM?
If not html_element will be null.
So make sure that all the above code is in a script tag that occurs somewhere in the document below the element (or is in a window.onload jQuery's document ready type event).