document.getElementById sometimes returns null - javascript

I have a line of code that is called in the onLoad event of a page, and it works fine. Inside the onload event, other functions are called, and trying the same line of code now returns null.
Code verbatim
riskInStateInputTypeElement = document.getElementById("riskInStateInputType");
Are there any instances where getElementById begins returning null after having returned the correct thing previously?
The line that works and the line that doesn't work are both in the same call stack, not separate events or threads. The Document readyStatus is 'complete' both time, so I dont think its a matter of the page not entirely loaded. Any ideas where I should look?

Did you check that it's referring to an element with that id? Maybe you misspelled id="riskInStateInputType" in your <div></div> (or whatever that id is referring to).
Are you deleting the content within that element before you call it the second time perchance?

Related

HTMLCollection returning null

I have already looked at other stackoverflow posts and none of them fix my error.
Trying to get the divs inside the outer div with class name "CodeMirror-code"
I'm building a chrome extension that directly modifies the html content of a specific webpage and when I call
const variable = document.getElementsByClassName('CodeMirror-code');
console.log(variable);
console.log("Length:", variable.length);
the output is: this
Now, when I try to call the first item of HTML collection like
variable.item(0)
this returns undefined or null
Other solutions says that you should surround the code in window.onload function in order for the DOM elements to be loaded in.
I did this, and there was no change.
Is there any way I can fix this error?
Update:
This is what is inside the HTML collection
Surround your code in a set interval function within window.onLoad and add some delay (like 2000 for 2 seconds). The only thing that gives HtML collection null is the loading latency of dom elements. If adding delay is still not helping then try to retrace the parents of your div and see till what point your js code is able to catch the expected div. Then check whether its the problem with load time or scope of the code.

Event handler stuck after changing body.innerHTML

I would like to change some text in my body html with code below. Replacing works fine, but after that it seems to stuck, can't get out of function, so next parts of my script cannot be executed.
Nothing will happen after clicking .another-button. I think problem is with line that change body.innerHTML because when I delete this line everything works fine.
$(".do-replace-button").on("click", function () {
//some different code
document.body.innerHTML = document.body.innerHTML.replace(regExp, newWord);
}
$(".another-button").on("click", function (event) {
//some code that won't execute
}
You are effectively replacing the innerHTML of your <body> with something else, which is a string, the result of your replace(). That string is parsed and built into new DOM elements and the old ones are getting replaced by the new ones.
Hence, the events you bound on the old ones are gone, because the elements are gone. One way to solve this would be to:
a) bind on document itself:
$(document).on('click', '.do-replace-button', function() {
// whatever...
})
b) find another, less aggressive way to achieve whatever it is you are achieving with that replace.
Do note it's not only your events that get removed, but any event bound by any library/plugin you might have loaded and already initialized by the time your script runs. I strongly recommend against running replace on innerHTML, especially on <body>.
The call to document.body.innerHTML and the right hand assignment that comes after it is completely replacing the html inside the document, or more specifically, the parser is building a completely new node tree inside the body so all of your HTMLElement nodes that may have previously had event listeners assigned to them are no longer there. I recommend you go another route of only replacing the the HTML that matches your regex instead of the entire HTML contents of the body element. Or you could have a function that is called inside the first event-listener callback that fires after the replacement of the body HTML, that will re-initialize the event listeners.

Fire ajax call on onclick and div

I am attempting to fire off an AJAX call based on the onclick event for a google map integration. The info_window_content function seen here: http://jsfiddle.net/6xw2y/ is the call to create the divs that reside within the map itself.
The "v" variable does in fact contain a store_id. So in the opening line of that function, it has the following:
var info_window_string = "<div class='maps_popup' id="+v.id+">";
Now I have an onclick event that I have duplicated and modified. The first onclick event works just fine and refreshes the panel as it should. The second onclick event doesn't work and the code for that is below:
$("#div").click(function(){
var store_id = $(this).find("div").attr("id");
var pathname = "ajax=1&store_id="+store_id+"&action=get_nearby_stores&distance="+distance+"&lat="+lat+"&lng="+lng+"&products="+$('#edit-products').val();
$("#pocp_content").load("file1.php?" + pathname);
});
That doesn't seem to work. I've also tried changing the div tag to be like this:
$("div").click(function(){
Which still doesn't work. As an added side hint. At one point I was able to get it to refresh but it was passing map-container as the store_id, instead of the id itself.
What am I missing here?
I agree with Joke_Sense10,
but I think you're probably not binding the event to the right DOM element.
Try to open up the developer console in your browser (while being on the side you develop this code for), and enter $("#div") to see if the element it returns is the one you expect. You can also use console.log($("#div")) in the code for that.
answer in comments
For a larger number of elements, always use .on() method as the latter will bind an single event listener on one of the topmost nodes in the DOM tree.
$(document).on("click","#"+v.id, function(){

Targeting an ID that is rendered by a script

I'm using a nifty little script called Tabifier (http://www.barelyfitz.com/projects/tabber/)
Now, long story short, this script, which I run in my head tag, creates a <ul> with <li>s containing <a>s. Also in the head tag it creates IDs for these <a>s. When I inspect the loaded site I can clearly see the ID tags present. However, I cannot call them using getElementById. I've been using
<script>
document.getElementById('rightpanelnav1').style.padding='200px';
</script>
as a sample script in different parts of my code but to no avail. I'm wondering wether it's the placement or order in which these things are defined in my code that's causing it not to recognize the ID. What do you think?
EDIT: I recieved a great answer below, but I still can't get 'rightpanelnav1' to register onclick events...? It's an , there shouldn't be a problem, right? And when I click it, the entire page has been loaded for several seconds...
Firstly, in order to access an element in the DOM, the element must be a part of the DOM (document). So if you place your <script> with getElementById in the page at a place prior to where the element is loaded, it will not see the element in the DOM.
Secondly, it is highly probable that this library you use does its modification on page load, which would mean that no matter where you place your <script> it would have no chance of seeing these elements before running.
As a result, you should have your script wait as well, and do this:
window.onload = function(){
document.getElementById('rightpanelnav1').style.padding='200px';
};
Or for a click event
window.onload = function(){
document.getElementById('rightpanelnav1').onclick = function(){
alert("clicked!");
};
};

Access $('selector').data in functions/objects

How do I access values set by $.data() inside a function or object
$('#timers').data('firsttimer', 100);
//prints 100
document.write($('#timers').data('firsttimer'));
function blah(){
//Prints nothing
document.write($('#timers').data('firsttimer'));
}
blah();
See this jsfiddle for easy access to test the code http://jsfiddle.net/JUfd8/
I'm having trouble with document.write() inside the function call for some reason, but it works fine if I use jQuery's .append().
function blah(){
$('body').append($('#timers').data('firsttimer'));
};
EDIT:
Found this stackoverflow question regarding document.write:
Why is document.write considered a "bad practice"?
An interesting sentence from one of the answers in that post:
As long as you don't try to use it after the document has loaded, document.write is not inherently evil, in my humble opinion.
So that may be the key to the trouble (or part of it, anyway).
The trouble is in "document.write()". Try to avoid it.
In this case, I believe your document.write is stomping on the DOM in some strange way, wiping out your timers div. Switching both of the document.write calls to alert calls instead (and adding a line to invoke blah()) allowed me to see both alert boxes, both showing the value 100.
<div id="timers"></div>
js code:
$('#timers').data('firsttimer', 100);
//shows 100
alert($('#timers').data('firsttimer'));
function blah(){
//Prints nothing
alert($('#timers').data('firsttimer'));
}
blah();
The behavior is not consistent across all browsers. Remember, on jsfiddle this code is already wrapped inside the window load callback since you chose the onLoad setting on the left. Once the DOM is loaded, any subsequent changes using document.write will replace the entire document.
Here's the relevant text from the HTML5 specs on document.write:
Unless called from the body of a script element while the document is being parsed, or called on a script-created document, calling this method will clear the current page first, as if document.open() had been called.
Here's how the browsers are behaving on my Mac given this code:
Chrome and Safari
Wipes out the document altogether. Even 100 isn't printed. Text nodes by themselves are being ignored here, but when wrapped inside some html tag - they show up. This code is the same as above with the values wrapped inside <b> and <i> tags respectively.
Opera and Firefox
Wipes out the document, then appends the text node "100undefined". It prints "undefined" because the node <div id="timers></div> does not exist anymore in the new document.
However, it does print "100" the first time you call document.write on Opera and Firefox
document.write($('#timers').data('firsttimer'));
because the function argument $('#timers').data('firsttimer') is evaluated first and since the original document is intact at this point, we get the value 100, which is then passed to document.write, that then recreates the entire document. Therefore, all subsequent calls to fetch the data associated with #timers returns undefined.

Categories

Resources