Can JQuery and Javascript be mixed together? - javascript

I am wondering if I could use query and javascript together so I could select an element by class with the javascript and then use javascript to work on that element. Sorry if that didn't make sense. Here is an example:
$('.nav_flag').src = "images/flags/"+userCountryLower+".gif";
Would that work, if not how do I get an element by class using regular javascript. Thanks!
EDIT:I know JQUERY is JavaScript but I was wondering if I could mix jquery selectors and javascript 'controller'-for a loss of a better word

To answer your question as asked, there are several ways to take a jQuery object, i.e., what is returned by $('some selector'), and get a reference to the underlying DOM element(s).
You can access the individual DOM elements like array elements:
// update the src of the first matching element:
$(".nav_flag")[0].src = "images/flags/"+userCountryLower+".gif";
// if you're going to access more than one you should cache the jQuery object in
// a variable, not keep selecting the same thing via the $() function:
var navFlgEls = $(".nav_flag");
for (var i = 0; i < navFlgEls.length; i++) { ... }
But you wouldn't manually loop through the elements when you can use jQuery's .each() method, noting that within the callback function you provide this will be set to the current DOM element:
$(".nav_flag").each(function() {
this.src = "images/flags/"+userCountryLower+".gif";
});
However, jQuery provides a way to set attributes with one line of code:
$(".nav_flag").attr("src", "images/flags/"+userCountryLower+".gif");
To answer the second part of your question, doing the same thing without jQuery, you can use .getElementsByClassname() or .querySelectorAll() if you don't care about supporting older browsers.

jQuery IS Javascript. You can mix and match them together. But you better know what you're doing.
In this case, you probably want to use .attr function to set value of attribute.

Use .attr() in jQuery, rather than mix the two here.
$('.nav_flag').attr('src', "images/flags/"+userCountryLower+".gif");
In many instances, it is fine to mix jQuery with plain JavaScript, but if you have already included the jQuery library, you might as well make use of it. Unless, that is, you have an operation which in jQuery would be more computationally expensive than the same operation in plain JavaScript.

You can do it with jQuery too:
$('.nav_flag').attr("src", "images/flags/"+userCountryLower+".gif");

keep in mind that jQuery is simply a library built upon javascript.
for any jQuery object, selecting its elements by subscription will return the corresponding dom element.
e.g.
$('#foo')[0] // is equivalent to document.getElementById('foo');

You need to add an index to the jQuery object to get the native Javascript object. Change:
$('.nav_flag').src = "images/flags/"+userCountryLower+".gif";
To:
$('.nav_flag')[0].src = "images/flags/"+userCountryLower+".gif";
To get elements by class name in Javascript you can use:
document.getElementsByClassName( 'nav_flag' )[0].src = "images/flags/"+userCountryLower+".gif";

To answer your question, you could use .toArray() to convert the jQuery object into an array of standard DOM elements. Then either get the first element or loop through the array to set all the elements with the class.
However, you could do this easier with pure jquery with attr or prop depending on the version:
$('.nav_flag').attr("src", "images/flags/"+userCountryLower+".gif");
Or use pure javascript:
if (navFlagElements = document.getElementsByClassName("nav_flag") && navFlagElements.length > 0) {
navFlagElements[0].src = "images/flags/"+userCountryLower+".gif"
}

Related

What is Javascript equivalent for this jQuery code

I am working on a project and not allowed to use jQuery. I am looking for equivalent plain Javascript code for below jquery:
$('img[alt="Apple Store Logo"]').parent().removeAttr("target");
I found below information :
jQuery Javascript
parent() : .parentElement
removeAttr() : removeAttribute()
Couldn't find how to construct above selector.
You can use querySelectorAll() to get NodeList that match the specified selector. Then implement forEach() to iterate over all the elements to remove the attribute from the element's parent node with
parentNode and removeAttribute().
Try the following:
document.querySelectorAll('img[alt="Apple Store Logo"]').forEach(function(el){
el.parentNode.removeAttribute("target");
});
Some older browser does not supprot forEach() on a NodeList . Use Array.prototype.slice.call() in that situation to implement forEach():
var images = Array.prototype.slice.call(document.querySelectorAll(selector));
images.forEach(function(el){
el.parentNode.removeAttribute("target");
});
The first part of your call is a simple DOM query retrieving all <img> elements with an alt attribute matching "Apple Store Logo".
$('img[alt="Apple Store Logo"]')
This can be done in vanilla JS easily enough:
document.querySelectorAll('img[alt="Apple Store Logo"]')
However,document.querySelectorAll returns a NodeList, not an Array. We can convert the NodeList to an Array by calling Array.prototype.slice on it:
Array.prototype.slice.call(document.querySelectorAll('img[alt="Apple Store Logo"]'))
My knowledge of jQuery is poor, but I believe the remaining methods are called iteratively against the elements returned in the query result. Therefore, assuming the intent is to get a reference to the img element's parent element, and remove its target attribute, the whole code block could be translated to:
Array.prototype.slice.call(document.querySelectorAll('img[alt="Apple Store Logo"]')).forEach(function (img) {
img.parentNode.removeAttribute('target');
});

Convert jquery function to javascript GSAP

I am doing some experimentation with GSAP library and i found one pen by Jonathan
http://codepen.io/jonathan/pen/qxsfc
which is pretty much i needed. i forked that pen and made my own and now i am trying to convert the same in vanilla js but the first step it self is not working.
i have converted the anonymous function to a named one and called on window.onload and its working. but now i have to replace all the $ calls of jquery selector to native selectors and its not working
the moment i change
var animContainer = $('.animContainer'),
to var animContainer = document.querySelector('.animContainer'),
my pen is
`http://codepen.io/osricmacon/pen/HAnrt`
any more suggestion on how to go about converting jquery to vanilla js
querySelector stops at the first element it finds, and returns a reference to that one element (or null if it doesn't find it). A closer analogue to jQuery's $() is querySelectorAll, which looks for all matching elements and returns a NodeList (which will be empty if none were found).
Separately from that, the key thing about jQuery is that it's set-based, whereas the DOM API is not. That's probably going to be the biggest thing for you to deal with when converting the one to the other.
For example, in jQuery, this sets the HTML of all div elements to "hey":
$("div").html("hey");
The equivalent using the DOM API might look like this:
var list = document.querySelectorAll("div"); // Or .getElementsByTagName
var i;
for (i = 0; i < list.length; ++i) {
list[i].innerHTML = "hey";
}
A common approach to making that less verbose is to reuse Array's forEach function (which is ES5, but can be shimmed for older browsers), like this:
// You'd probably do this once and reuse it
var forEach = Array.prototype.forEach;
// Where you want to use it:
forEach.call(document.querySelectorAll("div"), function(div) {
div.innerHTML = "hey";
});
Or, of course, to have a toolbelt of utility functions that do that under the covers. Which is, of course, exactly what jQuery is.
Finally, in many cases jQuery reuses the same functions as both setters and getters. The html function, for instance, sets the HTML of the elements in the jQuery set when you give it an argument, but gets the HTML of the first element of the set if you don't:
$("div").html("hey"); // Sets the HTML of all divs
console.log($("div").html()); // Gets the HTML of the *first* div
Note the assymetry: Setting applies to all elements in the set, but getting applies only to the first element in the set (ignoring any others). This is true of all of the functions that do dual duty (html, css, val, attr, prop, ...).

What does $($(this)) mean?

I saw some code around the web that uses the following statement
if ($($(this)).hasClass("footer_default")) {
$('#abc')
.appendTo($(this))
.toolbar({position: "fixed"});
}
What is the use of $($(this)) and why is that necessary here?
Yes, $($(this)) is the same as $(this), the jQuery() or $() function is wonderfully idempotent. There is no reason for that particular construction (double wrapping of this), however, something I use as a shortcut for grabbing the first element only from a group, which involves similar double wrapping, is
$($('selector')[0])
Which amounts to, grab every element that matches selector, (which returns a jQuery object), then use [0] to grab the first one on the list (which returns a DOM object), then wrap it in $() again to turn it back into a jQuery object, which this time only contains a single element instead of a collection. It is roughly equivalent to
document.querySelectorAll('selector')[0];, which is pretty much
document.querySelector('selector');
You can wrap $ as many times as you want, it won't change anything.
If foo is a DOM element, $(foo) will return the corresponding jQuery object.
If foo is a jQuery object, $(foo) will return the same object.
That's why $($(this)) will return exactly the same as $(this).
There is no specific need for double-wrapping and $($(this)) is exactly the same as $(this).
That said, I once found this double-wrapping in one file in my project, committed by another developer. Tracking the changes through revision, turned out that it started as $($(this).find('selector').first()) - that is, the result of some selector was wrapped to create a new object. Then for whatever reasons, the selector was removed and only the double-wrapping of this remained. Needless to say, on the next commit it was changed to $(this).
As explained before me, $($(this)) and $(this) are absolutely identical. jQuery returns the same jQuery object if you try to wrap it more than once.
Additionally, for performance considerations it is a good practice to reuse jQuery objects - it is quite expensive to create jQuery objects, especially the ones with complex selectors. Example:
var $this = $(this);
if ($this.hasClass("footer_default")) {
$('#abc')
.appendTo($this)
.toolbar({position: "fixed"});
}
Just google for 'jQuery best practices' - it will take a 30 min for you to learn these basics and you will use jQuery way more effectively.
There is no meainig of doing that.
The following code return the same:
console.log($($(this)).hasClass("footer_default"))
console.log($(this).hasClass("footer_default"))
a boolean value depenging on if the selected element has or not the class footer_default:
.hasClass( className )Returns: Boolean
Demo: http://jsfiddle.net/IrvinDominin/aSzFn/
$(this) and $($(this)) both return jquery object.
There is no difference between these two.

why does $('el')[0].className work but not $('el').className?

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');
}
});

You can wrap $() around an array of DOM elements, or around a jQuery object, but not around an array of jQuery objects

Not really sure how to phrase this question so it's generic enough. (and will rephrase, after I know what I'm asking). The problem, I believe deals with variables in a JQuery .find() function.
Problem: you can wrap $() around an array of DOM elements, or around a jQuery object, but not around an array of jQuery objects
The best I can do, at this time, is provide an example here
The problem code in the previous fiddle, is here:
////////////////Neither of the following works////////////////
//nodelevel = nodesWithMinuses.find('div.node.level' + levelnumber);
nodelevel = $(nodesWithMinuses).find('div.node.level' + levelnumber);
////////////////Neither of the previous works////////////////
Apparently you can wrap $() around an array of DOM elements, or around a jQuery object, but not around an array of jQuery objects.
Try changing this line:
var nodeWithMinus = thisplusminus.parent().parent();
to this:
var nodeWithMinus = thisplusminus.parent().parent()[0];
This will extract the DOM element and turn nodesWithMinuses into an array of DOM elements.
The variable nodesWithMinuses is an array of jQuery objects. You cannot apply jQuery method to anything else then a jQuery object. You have 2 options : either you declare nodesWithMinuses as a jQuery object and add objects to it via the add method :
var nodesWithMinuses = $();
//...
nodesWithMinuses.add(element);
// instead of nodesWithMinuses.push(element);
either find a way to convert the array to a jQuery object :
$($.map(nodesWithMinuses,function(el,i){return el.get(0)})).find('div.node.level' + levelnumber);
or traverse the array and search for the element in each object at a time :
var result = $();
$.each(nodesWithMinuses,function(i,el){
result.add(nodesWithMinuses.find('div.node.level' + levelnumber));
});
console.log(result);
In your code, nodeWithMinuses is an array but you're trying to wrap it in the jQuery function. That doesn't work on arrays. Using a variable in jQuery's find function is fine.

Categories

Resources