Do something in jquery if element has exact property & value - javascript

I want to do something in jquery if my element has a given property & value.
This is what I'm trying that doesn't work:
if ($('.myElement').css('opacity','1')){
console.log('test');
}
What is the correct syntax for this?

The second paramter of css() sets the style, not passing that parameter returns the current style for you to check against a string :
if ($('.myElement').css('opacity') == '1'){
console.log('test');
}

To get the css style we use $(element).css(propertyname);
to set style we use $(element).css(propertyname,value);
if ($('.myElement').css('opacity') == 1){
console.log('test');
}
.css()

Related

Adding active class based on current URL

I am trying to add 'active' class on my link. It is saying
Uncaught TypeError: document.querySelectorAll(...).each is not a function
Here is my code:
const current = window.location.href;
document.querySelectorAll("#nav-tab a").each(function(){
const $this = this;
if($this.attr('href').indexOf(current) !== -1){
$this.classList.add("active");
}
});
Can you help me? Or is there a better way to add a class name based on the current URL?
Thank you so much!
You have a few issues with your code. Your mainly confusing jQuery methods with regular native browser methods/conventions:
You need to use .forEach() and not .each(). The .forEach() method is a method on the NodeList that querySelectorAll() returns.
.attr() is not a valid method. To get an element's attribute you can use .getAttribute(). We can use .href here instead to get the href. Note that getAttribute("href") will retrieve the URL as it is in your mark-up, whereas .href will retrieve the full, eg, if you had href="/foo/bar", .href will give https://example.com/foo/bar, whereas .getAttribute() will return just /foo/bar.
Use the element parameter of the function instead of this. When you use .forEach() you're iterating over the elements in your NodeList (ie: the elements you selected), so you can access each using the first parameter of the forEach callback. The this value in the browser (if not in strict mode) will default to window, so it won't be the element like you're expecting it to be:
const current = window.location.href;
document.querySelectorAll("#nav-tab a").forEach(function(elem){
if(elem.href.includes(current)){
elem.classList.add("active");
}
});
I've also changed .indexOf(...) !== -1 to .includes(), which is a more modern way to check if a string contains another value.
I will point out that you can make your query selector more advanced, which will limit the number of elements you iterate:
const current = window.location.href;
document.querySelectorAll(`#nav-tab a[href*="${current}"]`).forEach(elem => {
elem.classList.add("active");
});
This uses the attribute selector a[href*=...] to select the a elements that have a href that contains the text in stored in current.
I think that you are mistaken jQuery and vanilla javascript
$.each is a jQuery function in you case you can use .forEach
$.attr is a jQuery function in you case you can use .getAttribute
const current = "#test-3";//window.location.href;
document.querySelectorAll("#nav-tab a").forEach((elem) => {
if (elem.getAttribute('href').indexOf(current) !== -1) {
elem.classList.add("active");
}
});
.active { color:red}
<div id="nav-tab">
Test 1
Test 2
Test 3
Test 4
</div>

difference between JS get element's attribute with elem.getAttribute(attr) and elem[attr]

I have a problem to get DOM element's attributes in JS. Here is code:
return elem.getAttribute(attr) || elem[attr] || "";
elem.getAttribute(attr) is used to get attributes like name or id, elem[attr] is used to get attribute like tagName. It works fine, until style came out.
In my case, I want to have "" when style attribute not set. But with above code, it will try elem[attr] when elem.getAttribute(attr) returns null. So if style is not set, I get all browser supported styles instead of "".
How to deal with this problem? Is there any better way than enum attributes?
Edit:
I want to write a general function to get element's attributes (such as name, style) or properties(such as tagName).
The main difference is elem.getAttribute(attr) try to get an attribute in the tag element, but elem[attr] try to get a property from an object, is important to know that elem inherits all properties from the Element Object, this properties are declared and in some cases defined, one of this properties is style.
In the particular case of the style property, by default this has been defined with an CSSStyleDeclaration, that's the reason you get attributes of style.
If you want only check if the attribute is in the tag, I suggest you only use this code:
return elem.getAttribute(attr) || "";
This is a code I use on my applications, so I'll just copy & paste it:
Object.defineProperty( Element.prototype, "hashAttr", { get: function(){
/* Bekim Bacaj 2008 */
var hash=[], i = 0, x = this.attributes;
while( x[i] ){hash[x[i].name] = x[i++].value};
return hash;
}})
;
which is, to my knowledge, the fastest possible.
This is a sample return from an element that has no inline or JavaScript assigned styles on its tag.:
>> media.hashAttr
{
width : "100%",
height : "100%",
id : "media",
src : "http://*****.***/stream/*****.mp4",
autoplay : "false",
poster : "http://******.***/thumb/*****.jpg",
type : "video/mp4"
}
Notice that, therefore, no offline style-attribute is present in the property list.
I have an answer. It handles tagName specially. It's not great. But it can get the job done.
var value = elem.getAttribute(attr);
if (!value) {
if (attr == "tagName") {
value = elem["tagName"] || "";
} else {
value = "";
}
}
return value;

Javascript ternary operators for method calls

I would like to be able to do this:
var b = $(this).is(':checked')
$('.perspective-col'). (b) ? show() : hide()
instead of
var b = $(this).is(':checked')
if(b) {
$('.perspective-col').show()
} else {
$('.perspective-col').hide()
}
Am I wishing for too much? Or is there some wonderful javascript syntax I haven't found yet? Or am I right in thinking that no such thing exists in JQuery thus far? (I'm using JQuery 1.9.0)
You can use this :
var b = $(this).is(':checked')
$('.perspective-col')[b ? 'show' : 'hide']()
You can call jQuery function by passing a string into the bracket []. Just insert a condition inside to decide which string you pass!
In general,
<any expression>.property
is equivalent to:
<any expression>['property']
The difference is that you can replace the literal 'property' in the brackets with an expression that calculates the property name. jQuery methods are just properties whose values happen to be functions.
But I actually hate that practice. You can also use jQuery .toggle()
jQuery has a method that does what you want called toggle():
$('.perspective-col').toggle(b);

How to check for the presence of an element?

I'm using the .length method in a conditional statement that polls the page for the presence of an externally-loaded object (I can't style it with jQuery until it exists):
function hackyFunction() {
if($('#someObject').length<1)
{ setTimeout(hackyFunction,50) }
else
{ $('#someObject').someMethod() }}
Is length the best way to do this?
If you are simply looking for a specific element you can just use document.getElementById
function hackyFunction() {
if (document.getElementById("someObject")) {
// Exist
} else {
// Doesn't exist
}
}
Yes you should use .length. You cannot use if ($('#someObject')) ... because the jQuery selectors return a jQuery object, and any object is truthy in JavaScript.
Yes, .length is acceptable and is usually what I use.
If you're looking for an ID there should only ever be one of those, so you could also write:
if($('#someObject')[0])
With jQuery, checking length works fine.
if (!$('#someObject').length) {
console.log('someObject not present');
}
Of course with vanilla JavaScript, you can just check with document.getElementById (if getting elements by id)
if (document.getElementById('someObject')) {
console.log('someObject exists');
}

Why does $('#id') return true if id doesn't exist?

I always wondered why jQuery returns true if I'm trying to find elements by id selector that doesnt exist in the DOM structure.
Like this:
<div id="one">one</div>
<script>
console.log( !!$('#one') ) // prints true
console.log( !!$('#two') ) // is also true! (empty jQuery object)
console.log( !!document.getElementById('two') ) // prints false
</script>
I know I can use !!$('#two').length since length === 0 if the object is empty, but it seems logical to me that a selector would return the element if found, otherwise null (like the native document.getElementById does).
F.ex, this logic can't be done in jQuery:
var div = $('#two') || $('<div id="two"></div>');
Wouldnt it be more logical if the ID selector returned null if not found?
anyone?
This behaviour was chosen because otherwise jQuery would regularly throw NullReference Exceptions
Almost all jQuery functions return a jQuery object as a wrapper around the Dom elements in question, so you can use dot notation.
$("#balloon").css({"color":"red"});
Now imagine $("#balloon") returned null. That means that $("#balloon").css({"color":"red"});
would throw an error, rather than silently doing nothing as you would expect.
Hence, you just gotta use .length or .size().
This is just how jQuery works.
$("#something")
Object 0=div#something length=1 jquery=1.2.6
$("#nothing")
Object length=0 jquery=1.2.6
You can come close to doing what you want by accessing the length the element, and combine with the ternary operator:
console.log(!!$('#notfound').length); // false
console.log(!!$('#exists').length); // true
var element= $('#notfound').length ? $('#notfound') : $('#exists');
console.log(element.attr('id')); // outputs 'exists'
As to the heart of the question:
Wouldnt it be more logical if the ID
selector returned null if not found?
No, not for the JQuery way of doing things - namely, to support chaining of JQuery statements:
$('#notfound').hide("slow", function(){
jQuery(this)
.addClass("done")
.find("span")
.addClass("done")
.end()
.show("slow", function(){
jQuery(this).removeClass("done");
});
});
Even though notfound doesn't exist this code will run without stopping script execution. If the initial selector returns null, you'll have to add in an if/then block to check for the null. If the addClass, find, end and show methods return null, you'll have to add an if/then block to check the return status of each. Chaining is an excellent way to handle program flow in a dynamically typed language like Javascript.
It returns true because to Javascript it is a defined object therefore not false, and jQuery will always give you a new object regardless of whether the element is found or not - however the array length will be zero, e.g.
$("span").length
If you have no <span>, this will be zero, but it could be 1 or more.
You can write your own plugin to avoid repeated if statements as a Jquery plugin, like I did for this one. It's fairly easy to do:
(function($)
{
/* Checks if a jQuery object exists in the DOM, by checking the length of its child elements. */
$.fn.elementExists = function()
{
/// <summary>
/// Checks if a jQuery object exists in the DOM, by checking the length of its child elements.
/// </summary>
/// <returns type="Boolean" />
return jQuery(this).length > 0;
};
})(jQuery);
Usage:
if ($("#someid").elementExists())
{
}
You could check the .length property of the jQuery object. Like this:
if($("#two").length > 0) { // exists...
} else { // doesn't exist
}
In short, you could think of the jQuery selector return value as a group containing 0..n elements, but never being null.
What you're probably really interested in is $("#two")[0], which will give you the first actual element returned by the selector.

Categories