How can I use getElementsByClassName(<classname>).outerHTML="" to hide a <div> when there are multiple names for the div's class? - html

I am trying to learn how to hide <div> sections on a webpage, using javascript getElementsByClassName("<classname>").outerHTML="".
It all works great if the element I am hiding e.g. <div class="someclassname">Some content I want to hide</div>. Or, I have success if using getElementByID("<divId>") if working with e.g. <div id="somedivID">.
The problem is, when wanting to hide a <div> that has no id and when there are multiple names listed for the div's class such as below:
<div class="cake forest carousel">Some content I want to hide.</div>
How can I hide such a div that has not id and no single class name?

For classes, you can use document.querySelectorAll() along with css selectors, like this:
document.querySelector('button').addEventListener('click', () => {
document.querySelectorAll('.cake')[0].style.display = 'none';
});
<div class="cake forest carousel">Some content I want to hide.</div>
<button>Hide content</button>
With classNames, remember that you can specify ALL the classNames (sometimes that is useful to pinpoint one element if there are other elements that contain part of the classList:
document.querySelectorAll('.cake.forest.carousel')[0] . . .
Also note that document.querySelectorAll() returns a collection, not a string - which is why it is necessary to use the [0] notation to choose the first element returned in the collection.
Using getElementsByClassName() is much the same idea - again, it returns a collection and one must either use the [0] notation to get the first element (usually if only one is returned), or a forEach() loop to choose the desired element based on other criteria.
document.querySelector('button').addEventListener('click', () => {
document.getElementsByClassName('cake forest')[0].style.display = 'none';
});
<div class="cake forest carousel">This div has classes cake, forest and carousel</div>
<div class="cake">This div only has class cake</div>
<button>Hide divs with classes cake AND forest</button>

Related

Customize html element by its class and id

I am trying to modify this project to show me some dates with colors, but i dont know how should i edit a specific element, lets say with id="3" what is inside the div with id ="March". Until now in all my atempts i only succeded coloring all divs with id="3".
So my question is how do i modify the proprietes of an element with id="3" && id="March"?
To target a div within a div do this:
<div id="3">
<div id="March"></div>
</div>
#3 #March {
color: purple;
}
Also try to use reasonable variable names in a camelCase naming convention.
Just use the DOM API for this.
In your case:
let march = document.getElementById('March')
let third_of_march = document.getElementById('3')
A small tip: IDs should be unique. The DOM API only returns one element. You should use classes in your use-case. This would make it even more simple.
let every_third_day = document.getElementsByClassName('3')
You can simply iterate over all elements and do whatever you want to do.

What is the difference between class and [class] in angular html

Looking for good practices about angular folder structure I stumble upon this piece of code:
content-layout.component.html:
<div [class]="theme">
<div class="mat-app-background">
<app-nav></app-nav>
<div class="container">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
</div>
</div>
As far as I understand, the class tag is used to bind this component HTML with a CSS class.
But the square brackets caught my attention, is there any real difference between the [class] and class for css binding? I can't hit the correct search term/feature name to google it myself
the brackets [] indicate that the value is a property in your component, so instead of saying apply the class theme to the element, it will look for a property theme in your component and use whatever is stored in there.
class="theme" // apply class theme
// Component
public theme = 'theme';
// HTML
[class]="theme" // use what's stored in property "theme"
or
[class]="'theme'" // use string 'theme'
[] is a way to bind the data between ts and HTML, so in this case, the theme is a variable, on the other side container is a direct property
what you understood about class is right, where coming to [class], based on the value, class will be applied to that element. if the value is true or some value then that class will be applied to that element or else it will ignore that class. so basically you are using a specific class for some functionality and not using it for another
eg: <div [class.classOne]="true"></div> // now div element will have classOne class because result is true or some value.
references for better understanding about classes:
https://angular.io/api/common/NgClass,
Difference between [ngClass] vs [class] binding

Using the Selenium Webdriver, how can I find all classes associated with a div?

I have a div with multiple classes based on the permissions of the logged in user.
When logged in:
<div class="btn deleteButton canDelete">
When not logged in:
<div class="btn deleteButton">
I need a way to determine whether or not a div which has the deleteButton class also has the canDelete class.
I tried getting a list of all Elements with deleteButton and all Elements with canDelete and comparing them, but that doesn't work for two reasons:
It's inefficient to loop through two potentially large lists rather than one.
There are potentially other divs on the page with canDelete. This means that just comparing the two lists of Elements isn't effective.
Did you try driver.findElement(By.cssSelector(".deleteButton.canDelete")); ?
One way to focus on the relevant area of a webpage is by creating containers and then looking for elements in these containers only. For example, you can identify and store your area of interest in a variable:
public static final String AREA_CONTAINER = "some_css_path";
then, once you have your area enclosed, you can look for your elements only within this area:
#FindBy(css = AREA_CONTAINER + "css_path") //here we are looking for specific elements within the area of interest
private WebElement element;
or in case of multiple similar elements:
#FindBy(css = AREA_CONTAINER + "css_path")
private List<WebElement> elements;
This both ways must work for you:
By.cssSelector(".deleteButton .canDelete")
or
By.Xpath(".//div[contains(#class,'deleteButton') and contains(#class,'canDelete')]")

div equal height animation on document ready

I have a script called equal-heights.js which works together with underscore.js. It equalize the divs to the size of the highest div with an animation (optional). The problem is that when I charge the page nothing happens, it starts to equalize the divs only when I resize the browser.
The initialising code on the HTML:
$(document).ready(function() {
$('.profile-panel').equalHeights({
responsive:true,
animate:true,
animateSpeed:500
});
});
You can see the equal-heights.js here: http://webdesign.igorlaszlo.com/templates/js/blogger-equal-heights-responsive.js
What should I do so that, when the page loads, the animation starts to equalize the divs automatically?
I created my own test and realized the issue is with the way the plugin has been written, namely that it only accepts one value for the class name, otherwise it will break.
This is because of the following line in the script:
className = '.'+$(this).prop('class');
What this does is that it takes the class property of your element and adds a dot (.) in front; a nice but not very scalable way of getting the current selector, because if you have multiple class names, it will only put a dot in front of the first one, so if you have...
<div class="profile-panel profile-panel-1st-row profile-panel1">
...it will transform it into...
$('.profile-panel profile-panel-1st-row profile-panel1')
...so understandably this will not work properly, as the dots are missing from the rest of the classes.
To go around this, until version 1.7, jQuery had a .selector property, that however has now been deprecated. Instead they're now suggesting to add the selector as an argument of your plugin's function as follows (and I tailored it to your situation):
First define an option called selector when calling the function:
$('.profile-panel-1st-row').equalHeights({
selector:'.profile-panel-1st-row',
// ...
});
Then setup the className variable inside the plugin as follows:
var className = options.selector;
Another thing you can do is the place the class you're using to activate the plugin as the first one for each element you want to use it on, so instead of...
<div class="profile-panel profile-panel-1st-row profile-panel1">
...do this...
<div class="profile-panel-1st-row profile-panel profile-panel1">
...then you can setup the className variable inside the plugin as follows:
var className = '.'+ $(this).prop('class').split(" ").slice(0,1);
This basically splits the class names into parts divided by space and takes the first one.
To have the best of both solutions, simply set className to the following:
var className = options.selector || '.'+ $(this).prop('class').split(" ").slice(0,1);
As to the animation, it only works on resize; that is intended, that's how the plugin has been built, you can play around with the original example of the plugin creator that I added to jsfiddle: http://jsfiddle.net/o9rjvq8j/1/
EDIT #2: If you're happy to change the plugin even more, just remove $(window).resize(function() in the if(settings.responsive === true) check and you'll have it working. ;)
if(settings.responsive === true) {
//reset height to auto
$(className).css("height","auto");
//re initialise
reInit();
}

How does jQuery work when there are multiple elements with the same ID value?

I fetch data from Google's AdWords website which has multiple elements with the same id.
Could you please explain why the following 3 queries doesn't result with the same answer (2)?
Live Demo
HTML:
<div>
<span id="a">1</span>
<span id="a">2</span>
<span>3</span>
</div>
JS:
$(function() {
var w = $("div");
console.log($("#a").length); // 1 - Why?
console.log($("body #a").length); // 2
console.log($("#a", w).length); // 2
});
Having 2 elements with the same ID is not valid html according to the W3C specification.
When your CSS selector only has an ID selector (and is not used on a specific context), jQuery uses the native document.getElementById method, which returns only the first element with that ID.
However, in the other two instances, jQuery relies on the Sizzle selector engine (or querySelectorAll, if available), which apparently selects both elements. Results may vary on a per browser basis.
However, you should never have two elements on the same page with the same ID. If you need it for your CSS, use a class instead.
If you absolutely must select by duplicate ID, use an attribute selector:
$('[id="a"]');
Take a look at the fiddle: http://jsfiddle.net/P2j3f/2/
Note: if possible, you should qualify that selector with a type selector, like this:
$('span[id="a"]');
The reason for this is because a type selector is much more efficient than an attribute selector. If you qualify your attribute selector with a type selector, jQuery will first use the type selector to find the elements of that type, and then only run the attribute selector on those elements. This is simply much more efficient.
There should only be one element with a given id. If you're stuck with that situation, see the 2nd half of my answer for options.
How a browser behaves when you have multiple elements with the same id (illegal HTML) is not defined by specification. You could test all the browsers and find out how they behave, but it's unwise to use this configuration or rely on any particular behavior.
Use classes if you want multiple objects to have the same identifier.
<div>
<span class="a">1</span>
<span class="a">2</span>
<span>3</span>
</div>
$(function() {
var w = $("div");
console.log($(".a").length); // 2
console.log($("body .a").length); // 2
console.log($(".a", w).length); // 2
});
If you want to reliably look at elements with IDs that are the same because you can't fix the document, then you will have to do your own iteration as you cannot rely on any of the built in DOM functions.
You could do so like this:
function findMultiID(id) {
var results = [];
var children = $("div").get(0).children;
for (var i = 0; i < children.length; i++) {
if (children[i].id == id) {
results.push(children[i]);
}
}
return(results);
}
Or, using jQuery:
$("div *").filter(function() {return(this.id == "a");});
jQuery working example: http://jsfiddle.net/jfriend00/XY2tX/.
As to Why you get different results, that would have to do with the internal implementation of whatever piece of code was carrying out the actual selector operation. In jQuery, you could study the code to find out what any given version was doing, but since this is illegal HTML, there is no guarantee that it will stay the same over time. From what I've seen in jQuery, it first checks to see if the selector is a simple id like #a and if so, just used document.getElementById("a"). If the selector is more complex than that and querySelectorAll() exists, jQuery will often pass the selector off to the built in browser function which will have an implementation specific to that browser. If querySelectorAll() does not exist, then it will use the Sizzle selector engine to manually find the selector which will have it's own implementation. So, you can have at least three different implementations all in the same browser family depending upon the exact selector and how new the browser is. Then, individual browsers will all have their own querySelectorAll() implementations. If you want to reliably deal with this situation, you will probably have to use your own iteration code as I've illustrated above.
jQuery's id selector only returns one result. The descendant and multiple selectors in the second and third statements are designed to select multiple elements. It's similar to:
Statement 1
var length = document.getElementById('a').length;
...Yields one result.
Statement 2
var length = 0;
for (i=0; i<document.body.childNodes.length; i++) {
if (document.body.childNodes.item(i).id == 'a') {
length++;
}
}
...Yields two results.
Statement 3
var length = document.getElementById('a').length + document.getElementsByTagName('div').length;
...Also yields two results.
What we do to get the elements we need when we have a stupid page that has more than one element with same ID? If we use '#duplicatedId' we get the first element only. To achieve selecting the other elements you can do something like this:
$("[id=duplicatedId]")
You will get a collection with all elements with id=duplicatedId.
From the id Selector jQuery page:
Each id value must be used only once within a document. If more than one element has been assigned the same ID, queries that use that ID will only select the first matched element in the DOM. This behavior should not be relied on, however; a document with more than one element using the same ID is invalid.
Naughty Google. But they don't even close their <html> and <body> tags I hear. The question is though, why Misha's 2nd and 3rd queries return 2 and not 1 as well.
If you have multiple elements with same id or same name, just assign same class to those multiple elements and access them by index & perform your required operation.
<div>
<span id="a" class="demo">1</span>
<span id="a" class="demo">2</span>
<span>3</span>
</div>
JQ:
$($(".demo")[0]).val("First span");
$($(".demo")[1]).val("Second span");
Access individual item
<div id='a' data-options='{"url","www.google.com"}'>Google</div>
<div id='a' data-options='{"url","www.facebook.com"}'>Facebook</div>
<div id='a' data-options='{"url","www.twitter.com"}'>Twitter</div>
$( "div[id='a']" ).on('click', function() {
$(location).attr('href', $(this).data('options').url);
});
you can simply write $('span#a').length to get the length.
Here is the Solution for your code:
console.log($('span#a').length);
try JSfiddle:
https://jsfiddle.net/vickyfor2007/wcc0ab5g/2/