I have a jQuery code as follows;
var favorites = $("#favorites");
var favoritesFooter = $("#favoritesFooter",favorites);
I am not sure what does the comma mean in the 2nd statement $("#favoritesFooter",favorites);
Also what would the following statement do or represent in the above case;
favoritesFooter.prev().after(newHTML);
It's the second parameter to $(). As explained in the documentation:
Selector Context
By default, selectors perform their searches within the DOM starting at the document root. However, an alternate context can be given for the search by using the optional second parameter to the $() function. For example, to do a search within an event handler, the search can be restricted like so:
$('div.foo').click(function() {
$('span', this).addClass('bar');
});
When the search for the span selector is restricted to the context of this, only spans within the clicked element will get the additional class.
Internally, selector context is implemented with the .find() method, so $('span', this) is equivalent to $(this).find('span').
The second statement means "search for element with ID of favoritesFooter inside the jQuery object favorites".
As you're dealing with ID which should be unique, it's pointless - $("#favoritesFooter") is the best practice.
Regarding favoritesFooter.prev() it's also pointless, assuming the ID is unique so you have collection with only one element thus prev() will return empty jQuery collection.
The .prev() will take the previous DOM element - in your case, it will push newHTML right before the favoritesFooter element.
Related
I have a function that requires a HTML element to perform the action on. I request the DOM selector as a parameter
function(document.body);
where element is the DOM query but somewhere else in the function I need the query as a string. Is it possible to turn the object into it's original string type? And if so, how?
You can do it the other way around. Pass your function a selector string:
functionName('body')
And then retrieve the relevant DOM element using .querySelector():
var el = document.querySelector(string);
The approach you are using is not going to produce the right results consistently in my opinion.
Passing in the element is going to mean that the element must be found beforehand and also is going to practically prevent finding other elements of similar location due to a lack of information.
Passing in a selector is an option, and then using that going forward if you need to find a similar set of elements but sometimes the selector is too complex to be placed in one string - for example if it needs filtering or some other metric.
Your best bet is to accept a callback function that returns the desired element or set of elements when you are dealing with complex selectors or locations for elements. It can simply return the same element each time if it is basic, or if it is more complicated the callback can access the DOM, filter based on some metric, and then return the subset which at times is ideal.
A callback function will provide the full amount of support without needing to always have a conversion to query string which is not always possible for complex structures.
If I understand you correct you could to this
function (elem) {
if (typeof elem === 'string' || elem instanceof String) {
elem = document.querySelector(elem);
}
var target = elem.querySelector(...);
}
To get the HTML string of an element use 'innerHTML'.
Temporary parent:
var div = document.createElement("div");
Append desired element to parent:
div.appendChild(document.body);
Test result:
alert(div.innerHTML);
If you are trying to get the string of the resulting element of 'querySelector()':
div.appendChild(document.body.querySelector('yourClass'));
The temporary parent ensures that you get the tags for the element returned. Otherwise you would only get the string for its child elements. If you want to use 'querySelectorAll()', just loop over the returned node array.
I was wondering what the difference between jQuery selectors $("#fake-div) and JavaScript selectors getElementById("fake-div"). First, are these even called JavaScript selectors?. I know jQuery returns the jQuery object whereas JavaScript selectors returns the DOM element; however, given these two blocks of code:
jQuery Selector
var post = $("#postid");
var reply_list = post.find(".replies_ul");
var current_reply = document.createElement("li");
current_reply.setAttribute("class", "reply_li");
reply_list.insertBefore(current_reply, reply_list.firstChild);
JS Selector
var content_list = document.getElementById("content_ul");
var current_post = document.createElement("li");
current_post.setAttribute("class","content_li");
content_list.insertBefore(current_post, content_list.firstChild);
The jQuery Selector ends up removing the list from the DOM when the last line of code is called, and the JavaScript selector successfully inserts the list item at the top of the list. I'm looking for an explanation as to what is going on.
The jQuery insertBefore in your code is invalid, it takes two arguments whereas the jQuery accepts only one:
.insertBefore( target )
Description: Insert every element in the set of matched elements before the target.
And the normal one:
Node.insertBefore
Description: Inserts the specified node before a reference element as a child of the current node.
parentElement.insertBefore(newElement, referenceElement)
The difference is not on the selector but on the method / function that you are calling.
You are using the jQuery insertBefore function and comparing it with the javascript insertBefore function.
In jQuery the insertBefore function has only one parameter and therefore you are using it wrong.
If you want to make use of the Javascript function insertBefore instead of the jQuery one, then you have to convert your jQuery object reply_list to a Javascript one.
You can do this by using .get(0) or [0] like so:
reply_list[0].insertBefore(current_post, content_list.firstChild);
//or like this
reply_list.get(0).insertBefore(current_post, content_list.firstChild);
In your first block of code, the reply_list is a jQuery object; meaning it doesn't actually have a .firstChild property.
Change it to this:
reply_list.get(0).insertBefore(current_reply, reply_list.get(0).firstChild);
Please note the differences between jQuery's insertBefore and JavaScript's insertBefore
anyone know where can I get information about this Type of selection in jquery
I found it in a .js file and I want to know about it.
I focus on Jquery api doc but in vain I dont find it.
var obj=$('#id1');
var t = $('.slidenews',obj).length;
exactly that what I want to know about.
var t = $('.slidenews',obj).length;
$('...', element) looks for ... in element instead of the whole document. So in this case, it will look for all elements with class slidenews in the #id1 element.
.length returns the number of such elements found
Therefore, if obj contains the element with ID id1, then $('.slidenews',obj).length returns the number of elements with class slidenews that are contained inside the element with ID id1.
Relevant documentation:
jQuery(selector, [context])
selector
Type: Selector
A string containing a selector expression
context
Type: Element or jQuery
A DOM Element, Document, or jQuery to use as context
length
Description: The number of elements in the jQuery object
$('.slidenews',obj) is basically context selector. It will be converted into obj.find('.slidenews') and .length returns the no of such elements
Reference
Selector Context
By default, selectors perform their searches within the DOM starting at the document root. However, an alternate context can be given for the search by using the optional second parameter to the $() function.
It same like:
obj.find('.slidenews')
In your case: obj - must be DOM object. if obj is falsy it will be replaced to document
I noticed that className property doesn't work inside jQuery without the index, why is that?
Also, are there other common JS properties / methods that don't work as expected inside jQuery?
HTML:
<div class="par">test</div>
JQuery:
$(function () {
var el = $('.par');
el.className += ' new class'; // doesn't work
el[0].className += ' new class'; // works
});
var el = $('.par'); returns a jQuery object. className is a property on Element and not on jQuery object.
The jQuery object has an array like definition so el[0] returns the underlying Element which has className property.
As far as I know, jQuery doesn't like developer updating its property directly. It simply exposes variety of utility functions for easy developement.
Quoting on a nice comment from David Thomas below,
jQuery methods can only be used on jQuery objects; native DOM properties/methods can only be used on native DOM nodes
Note: var el = $('.par'); returns a collection of Element and el[0] returns the first element in that list.
You could use .addClass to add a class to the element.
To the first element,
el.eq(0).addClass('new_class');
To all elements,
el.addClass('new_class');
More Reading:
https://developer.mozilla.org/en-US/docs/Web/API/element
https://developer.mozilla.org/en-US/docs/DOM/element.className
var el = $('.par');
gives you a jQuery object, which may contain one or more DOM elements.
var el = $('.par')[0];
returns the first DOM object in the selection of that jQuery object. className is a property on a DOM element, not on a jQuery object
$('.par').attr('class');
would be the jQuery way to get the className of the first element.
If you just want to add a particular class to elements matching another class, you can use
$('.par').addClass('testclass');
This will add the test class to all elements with the par class, while your method will only add it to the first element on the page.
Other properties
Also, are there other common JS properties / methods that don't work as expected inside jQuery?
Most dom properties will not work directly on a jQuery object. You can use [0] to get the raw dom element for the first matched element for those. However most of them also have straightforward equivalents in jQuery. The advantage of using the jQuery versions is that they're often simpler, and work consistently across browsers. Native dom properties tend to be faster to access though.
className is part of the api for a DOM element.
var el = $('.par'); will return a jQuery object with an array of elements.
Using el[0] accesses the first element which has access to the api.
jQuery provides an easy method for adding classes to an element or group of elements matched by a selector called addClass. You could use this:
var el = $('.par');
el.addClass('new class');
Also note that it is usually best practice to name variables which contain a jQuery object with $ like this:
var $el = $('.par');
The jQuery DOM object is actually a list of matching elements. Since you're setting a variable on a list of DOM elements, jQuery can't apply them to the entire list. el[0] is the first matched element. (If you have more than one element, using el[0] will only set the first matched element, and if there aren't any matches, el[0] will raise a ValueError.) You should probably use jQuery's builtin class manipulation functions:
el.addClass("new class");
to remove the classes:
el.removeClass("new class");
and to toggle them:
el.toggleClass("new class");
This might not be directly related to the question, but if you're working with jQuery, then you should also be using jQuery's easy to use methods to modify the classname's of all DOM elements within a jQuery object.
http://api.jquery.com/addClass/
http://api.jquery.com/toggleClass/
http://api.jquery.com/removeClass/
$(function () {
var cname = $('.par').attr('class'); // get class attribute
if (!$('.par').hasClass('some-new-class')) {
$('.par').addClass('some-new-class');
}
});
In JavaScript if I append a child which has an ID to another place then it's removed from original location where they currently are.
In javascript I have an event where I can get selector by using this inside the function
$('.').event(function(){
this
});
This is passed to another function and they work fine. Now I want to pass the clone instead of the object; and remember that this does not have ID.
The old code works by passing this to function as DoSomething(this)
if I make a clone using jQuery clone then I have the jQuery object. So how do I get a reference to this instead of the jQuery object when working with the clone?
var clone = $(this).clone() // this is jQuery object.
//how do I get this out of clone?
if I append a child which has an ID to another place then it's removed from original location where they currently are.
Yes, but the same is true of a child node that doesn't have an id attribute as well. An id is only an easy way for you to get a reference to the Element node object; it makes no difference to DOM insertion of cloning behaviour.
In javascript I have an event where I can get selector by using this inside the function
No, this in an event handler gives you the DOM Element node object, not a selector string. A Node can be turned into a jQuery wrapper around it using $(node) and a selector can be turned into a jQuery wrapper on the list of matching nodes using $(selector) but other than this overloading in the jQuery API they're completely different animals.
To pull a Node back out of a jQuery wrapper you can use the get() method or simple array-like access:
var clonedNode= $(this).clone()[0];
var clonedNode= $(this).clone().get(0);
to taste. (get() has some extra features which you don't need here.)
To get the selector used to create a jQuery wrapper you can use the selector property, but this won't return anything if the wrapper was created from a node object ($(this)) rather than a selector.
$(this).clone().get(0). This will get the first matching DOMElement from the jQUery object.
To get the DOMElement object from a jQuery object use get(0):
var clone = $(this).clone(); // this is jQuery object.
var el = clone.get(0); // this is DOMElement object