I am following a tutorial on W3Schools to make a JS slideshow. While this seems simple enough, even after directly copying their code, my JavaScript is having some VERY nonsensical and frustrating errors. The issue seems to be that, when my function accesses document.getElementsByClassName("slides")[some_index_here], it returns undefined, despite that, when I access the SAME element in the exact same way through inspect element console, what I am looking for shows up. What is going on?
I found that I needed to wrap what I did in a window.onload function, because the code was executing before elements existed.
Related
Code:
const elements = $(".container .element").first().nextAll().addBack();
Here's my HTML:
The code is supposed to grab the first element and all the content after it. Depending on the HTML, this could return at a lot of different things, including nothing if I have a typo in my jQuery code. If the code that follows doesn't function correctly, how do I see what's inside elements for troubleshooting purposes?
I tried logging elements.html(), but that only printed the contents of the first element.
I tried using the Firefox debugger on elements, but the object is very complex, contains a lot of irrelevant troubleshooting information, and I couldn't figure out how to find what the jQuery object actually represents.
The only way I could figure out my code was correct was by logging elements.text(). That printed the text inside every element, and by doing that, I knew I had grabbed each one. It didn't tell me I grabbed the BR tags, but the documentation for nextAll said it would, so the gave me another faith it was doing what I wanted (I don't like relying on faith). The other problem with this solution is that it's highly contextual and won't work in all situations. There won't always be text in the HTML.
I'm out of ideas. How do I see what's inside a jQuery object for troubleshooting purposes?
Use
console.log(elements.get())
The jQuery get() method with no arguments returns the contained DOM elements as an array.
I am using jspmBundleSFX.
In one of my index.html in one of my directories, when I type, $("#sfsdfasfsdaf").append in console.
I get function(){return x(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=s(this,a);b.appendChild(a)}})} Chrome says it belongs to main.js which is the bundled and uglified js.
$("#sfsdfasfsdaf") Does not even exist, what is hapenning?
This also happens with ids that exist $("#canvas").append I get the same result.
appendChild however returns undefined
In another index.html in another directory everything works absolutely fine. I have no idea how to fix this problem. Both index.html include the main.js uglified file.
EDIT: I replaced $("#canvas"); with document.getElementById('canvas'); It works fine now. However I still have no idea why this problem was happening. Did some script overwrite or have conflicts with jQuery?
$("#sfsdfasfsdaf") Does not even exist, what is hapenning
The reason is $(selector) will always return a jQuery object regardless whether there are matching elements existing or not. That object will always include a property append which is a function. There is no jQuery method appendChild which is why you see undefined.
Beyond that it is not clear at all what you aare trying to do or what higher level problem you have
You are creating a jQuery object. It may be an empty jQuery object (if the element doesn't exist or, more accurately, if no elements match the selector) but it is still a jQuery object.
As such, it still has all the jQuery methods, such as .append. It just won't do anything if you call it.
Vanilla JavaScript, however, gives null if the element doesn't exist (eg. document.getElementById('herpaderp') will be null), and null doesn't have the methods that an element would have such as appendChild.
Personally I consider this a good thing in general - if I say I want an element and it doesn't exist, chances are there are bigger problems and an error should be thrown, but jQuery will continue happily along.
Imagine this: You want to make some things with a XML element you receive in a method. So you try this:
function makeNiceThings(XMLDOM){
if(XMLDOM.getElementsByTagName("err")){
makeReallyNiceThings(XMLDOM.getElementsByTagName("err")[0].childNodes[0].nodeValue);
}
}
So, Javascript tells you you're trying to call childNodes[0] from a null reference. But if you try:
function makeNiceThings(XMLDOM){
if(XMLDOM.getElementsByTagName("err")[0]){
makeReallyNiceThings(XMLDOM.getElementsByTagName("err")[0].childNodes[0].nodeValue);
}
}
It works flawlessly.
However, you update the page sometimes, and both are working again, no problems at all.
I have already faces so many situations like this, that I really want to know if there is a place I can show these bizarre errors in order to make javascript even better. Google returned me nothing but places to discover programmer errors. Ideas?
Well, I don't see an issue there. In the first example you may get and empty array which is not nothing. So the condition becomes true. Whereas in the second example you do what you really meant to do — check if there's an element with index 0.
Or, if you are really convinced that this is not your fault, you should do what Rocket Hazmat said:
Bugs with JavaScript itself should be reported to the bug tracker of
the browser. Though, chances are this is not a bug with JavaScript.
But most probably this is a mistake in the code. If there's no err elements, you'll get an empty array and the condition will be evaluated to true; but there's no 0th element — that's why you get an exeption.
Hope that was clear.
So, this is maybe just a question for interact.js users or I am missing something completely..
I was looking for a javascript library that provides me with drag/drop/scale/rotate and touch functionality for all those given functionalities. So, I stumbled upon interact.js, yet I seem to have a problem referencing elements while using the onDrop method:
I'll just take the code of the interact.js page, which I'm providing you here: http://jsfiddle.net/Zyy2N/2/
The part that is making problems is:
$(event.relatedTarget.id).hide();
which doesn't do anything, yet also doesn't throw any errors. More so:
$('#yes-drop').hide();
works, so does:
console.log(event.relatedTarget.id);
which returns the id as expected. Is this an error?
Solution: One should actually use the correct syntax if one wants code to run correctly...
$('#'+event.relatedTarget.id).hide();
This would actually be a correct and working solution :
http://jsfiddle.net/Zyy2N/3/
Sligthly better:
$(event.relatedTarget).hide();
http://jsfiddle.net/Zyy2N/8/
function myfunction(id){
//code
$("#mydiv").hide();
};
But 'mydiv' is dynamically added , and the function is not working .
Since the part of the code you shared seems to be fine, I suspect that there is something else wrong with your code.
Try to debug it. It is not that hard and let's you figure out errors on your own much faster than looking at your code really hard.
First if would be good to know if you reach that line of code in question. You can open the developer console and add a breakpoint to the line in question, or you can add alert("this line is reached and executed") in your code, and then you will know if that line is reached and executed.
If you reached the line in question, it would be good to know things about what is happening there:
For example it would be good to know if $("#mydiv") matches anything. If you are afraid of the developer console, you can always try: alert($("#mydiv").length). If it's 0, there is nothing matched, if it's 1, you have matched an element that will be hidden if you call $("#mydiv").hide(). If it's 0, you haven't been able to match an element. That means that there is currently no elements in your DOM with the id of mydiv. It does not matter if it should have been added dinamically or should be there from the start, it's not there. You might have made a spelling mistake in the id.
Since you are matching something added dynamically by it's id, it is possible that you already have an element with the ID mydiv. If there is more elements with the same ID, only the first one will be matched! More than one elements with the same ID is not just bad practice, it's invalid, and will possibly lead to more bugs and headaches later.
If you are sure that you match the correct element and it's not hidden when you call $("#mydiv").hide(), than there is always ways to look for the problem: for example if you open the javascript developer console, the javascript errors will be listed there. Be sure to check them if they are related to this problem.
Happy bug hunting!
Make sure that you're calling $("#mydiv").hide(); after you've added #mydiv. The code itself will work absolutely fine, provided you've already added #mydiv.