How do I troubleshoot a jQuery object? - javascript

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.

Related

JavaScript variable equals jQuery selector creates open and closing tags. Why?

Please be nice. My first question here. I'm learning JavaScript and jQuery. Google isn't much help because I don't know how to ask the right question. Need human intervention please. I'm trying to figure out what is going on with this simple bit of code:
var myVar = $("<p>");
This creates an opening and closing <p> tag and I don't understand why.
Next, I'll add this paragraph to an existing element #myDiv. For example:
$("myDiv").html(myVar); results in the following:
<div id="myDiv"><p></p></div>
Continuing...
$("myDiv").html(myVar.text("A string for the paragraph"));
Results in:
<div id="myDiv"><p>A string for the paragraph</p></div>
Why does that first snippet create an opening and closing <p> tag? What is this called?
It's simply a more concise method of this in pure JavaScript:
var myVar = document.createElement("p");
And that goes to jQuery like this:
var myVar = $("<p></p>");
And because it's jQuery, and it gets more and more concise, it eventually becomes:
var myVar = $("<p>");
This is the right kind of question to be asking while you learn, so good for you! That being said, one SO post won’t be able to completely answer it, at least in the way that I think you're asking it, but I (we) will give you what I can.
To begin, the way that JavaScript interacts with HTML is through the Document Object Model (DOM). This is like taking an entire HTML document and cutting it up into the individual elements, tags, attributes, etc., and then constructing a representation of that document in "plain" JavaScript as a (very large) Object. The variable name assigned to this Object is document. This special Object has all sorts of magical properties and methods (functions) that can be used to read and update any piece of the DOM (which ultimately translates into the HTML you see in your browser).
What I've described so far has nothing to do with jQuery, and all of that manipulation can be done with plain JavaScript (like Jack Bashford's answer, for example). However, due to the way that browsers and other web technologies have evolved over the years, many "gotchas" exist (or used to exist) when it comes to doing any of this stuff in "plain" JavaScript. jQuery is an incredibly important tool, historically speaking, because it provided a "standard" way to write very direct code to do all of this DOM reading or manipulation, and the jQuery library would make sure that all of the "gotchas" were avoided.
So, what is jQuery (in code, that is)? Well, there could be many technical answers to that, and one important technical answer is that it is an Object, because in JavaScript, (almost) EVERYTHING is an Object. However, let's focus on the question at hand, and the code you provided:
$("<p>");
Here, the dollar sign IS jQuery (or a variable pointing to the jQuery Object). The parentheses that follow indicate that the jQuery Object is being called as a function. It is like saying, in code, "do the jQuery thing with this string of characters: '<p>'." Taking a step back, the full statement
var myVar = $("<p>");
is saying "this variable 'myVar' is now pointing to the results of whatever doing the jQuery thing with '<p>' will give us."
The "magical" thing about writing in jQuery is that the syntax almost always feels the same (and gives it an intuitive feel).
Grab the jQuery Object. This is usually the variable $, but jQuery will also work.
Call the function ($()). There are cases where you don't, like ajax requests, but that's a separate topic and use case.
Supply it with any kind of selector ($('#myDiv')), which is a way of referring to specific HTML elements based on their properties and location in the document (here we are looking up a specific element based on it's id).
Work with the result ($('#myDiv').html(...etc))
I'll point out at this point that the jQuery documentation should be handy so you know what you're getting as a result of any specific function call, but in almost all cases, this function will return another jQuery Object that holds references to whatever elements you selected or manipulated during that function call.
In the latter example, we will receive a reference to the #myDiv element, on which we then call another function (.html()) that will either read or update the contents of that html element.
In the case of the line you specifically asked about, the syntax used to "select" a 'p' tag will be interpreted by jQuery not to look up all 'p' elements in the document (that syntax would be $("p")), but rather to create a single new 'p' element and store it in memory as a jQuery Object that points to this newly created element. Read more about that syntax and its possibilities here.
Well, I hope that was helpful. I sure enjoyed writing it, and even learned a few things along the way myself.

Is append and appendChild getting overwritten?

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.

Javascript DOM elements hide class and the element not present are same?

I am currently working on a project where most of the code has been written by someone else . I was supposed to do some slight modifications in the existing script to incorporate changes in a new file. I came across a situation where it was very confusing . The scenario is as cited below:
I have an element named as complextabs and it is being used for almost all the pages, except for the one which is being created newly. The situation is there is a code snippet that is written as $('.complextabs').hasClass('.hide'). this incredibly returns the same as when the element complextabs is not even present in the page. Can someone please throw some light on this
And yeah, I am working on Backbone.js . Has this got something to do with the use of Backbone.js
Any suggestion and advice is highly appreciated
Nope, that has nothing to do with the use of Backbone.
Consider the following:
$('.asdasda').hasClass('hide')
This will return false, and it should return false because $('.asdasda') does not return any results. Just running that will yield a JQuery wrapper over an empty list and since there are no elements then obviously there's nothing in there with the css class hide.
If you want to check that there is an element with both the complextabs and the hide class then use $('.complextabs.hide').length.

apply jquery effect on dynamically added div

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.

Is it a bad practice to reference Javascript objects from DOM elements?

As a "best practice" for front-end developers, is it bad to use the "control" property to reference back to the Javascript object?
Here's a link to the property in question:
https://developer.mozilla.org/en/XUL/Property/control
I've seen a lot of Javascript functions that reference DOM elements using selectors and then perform DOM manipulation that way. But what if we started by traversing through the DOM tree and we have the DOM element first?
EDIT 1
Okay, it seems like there are some interest here but no contributions for some reason. This started as a conversation between me and my co-worker. He was concerned about circular references and possible cases of losing references... does that apply here? I thought as long as we don't call delete <javascript object> then we're fine.
EDIT 2 I found this: JQuery methods and DOM properties
In my world right now, I'm using the Microsoft AJAX Library where we created multiple ScriptControls and put them on various pages; which in turn, (the ScriptControls) get "modified" by page's events and sometimes events of other ScriptControls. When pages need to do something with the DOM element, the Javascript would use the respective Javascript Object's methods.
However, it seems in JQuery (based on the other question), it's common to get the DOM element then use .get(0) to grab the JQuery object out of it (if it exists).
So I guess this is a witch hunt so far and there's still no right answer to my question :(
I know I'm still lacking an example but I'm not sure how to approach this.
I am not too sure what exactly you're referring to. Could you provide a simple code example? Otherwise, your question is a bit vague IMHO. I'll give it a shot anyways:
I do not understand why there would be any lost or circular references. The control attribute is just the id (string) of the "controlling" DOM Element, not a reference to the actual DOM Element. If you delete label.control it will no longer be associated with the other DOM Element.

Categories