javascript remove parent div where particular class appears in hierarchy below - javascript

First time question on this site. Sorry if I have failed the formatting test.
I am almost completely ignorant about javascript but I have been told I need it to solve this problem. I have a page where there are multiple divs with the same class. Each has a multi-level hierarchy beneath it. I want to stop the parent displaying if any of its children contain a div of a particular class. e.g. In the following code I want to stop all divs with class of "classa" displaying if one of their direct or indirect children contains class of "classb draft". So here, none of divb would display.
<div id="diva" class="classa">
<div id="divaa">
</div>
<div id="divab">
<div id="divaba">
<div id="divabaa"
<div id="divabaaa" class="classb">
</div>
</div>
</div>
</div>
</div>
<div id="divb" class="classa">
<div id="divba">
</div>
<div id="divbb">
<div id="divbba">
<div id="divbbaa"
<div id="divbbaaa" class="classb draft">
</div>
</div>
</div>
</div>
</div>

You are not closing div in
<div id="divabaa"
You can use querySelectorAll() to select all the children with that class (draft). Then use forEach() to loop through all the matching elements to find the closest() div with .classa to set display property to none.
var elements = document.querySelectorAll('.classa .draft');
elements.forEach(function(el){
el.closest('.classa').style.display = 'none';
});
<div id="diva" class="classa">
<div id="divaa">
</div>
<div id="divab">
<div id="divaba">
<div id="divabaa">
<div id="divabaaa" class="classb">
Without Draft
</div>
</div>
</div>
</div>
</div>
<div id="divs" class="classa">
<div id="divba">
</div>
<div id="divbb">
<div id="divbba">
<div id="divbbaa">
<div id="divbbaaa" class="classb draft">
Draft
</div>
</div>
</div>
</div>
</div>

Related

Jquery: selecting grand grand parents by class

I'm trying to select an element by clicking on its grand grand grand child. But I can't find the way without using parent().parent() etc.
General HTML
I have an HTML divided in pages
<div class="page"></div>
<div class="page"></div>
<div class="page"></div>
Inner page HTML
<div class="page">
<div class="">
<div class="to_move">
<div class="">
<div class="clicked_element"></div>
</div>
</div>
</div>
</div>
When clicking clicked_element I want to copy to_move class element to previous page.
The inner structure of the page element is not always the same, that's why I want to avoid using multiple parent().
I tried
$(this).parentsUntil('.page').html()
But I get only clicked_element parent.
$(this).parents('.page').html()
With this parents() option I get undefined.
$(this).closest('.page').html()
Again I get undefined.
Any clues welcome.
You could very well use closest :
$('body').on('click', '.clicked_element', function() {
$(this).closest('.page').clone().appendTo('body')
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
<div class="page">
<div class="">
<div class="to_move">
<div class="">
<div class="clicked_element">Click me to copy my whole class</div>
</div>
</div>
</div>
</div>
$(this).parents('.page') should work. I'm guessing you're binding the the wrong event. The key to this answer is not the selector ($(this).parents...) but the event binding ($(".clicked_element").click...). In your case, I guess that this is not the element you were looking for because the event binding is probably wrong.
$(".clicked_element").click(function() {
alert($(this).parents('.page').attr('printme'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="page" printme="You found me!">
<div class="">
<div class="to_move">
<div class="">
<div class="clicked_element" style="width: 250px; height:250px; background-color: blue">
</div>
</div>
</div>
</div>
</div>

add unique class in randomly position to the div with the same class

I need all divs with the class "nprotagonistas__bg" only one add the class "hover" randomly.
<div class="nprotas">
<div class="container">
<div class="row">
<div class="col-6">
<div class="nprotagonistas">
<div class="nprotagonistas__bg grey">
</div>
<div class="nprotagonistas__content lectores">
</div>
</div>
</div>
<div class="col-6">
<div class="nprotagonistas">
<div class="nprotagonistas__bg white">
</div>
<div class="nprotagonistas__content controladores">
</div>
</div>
</div>
<div class="col-6">
<div class="nprotagonistas">
<div class="nprotagonistas__bg black">
</div>
<div class="nprotagonistas__content videointercomunicacion">
</div>
</div>
</div>
<div class="col-6">
<div class="nprotagonistas">
<div class="nprotagonistas__bg red">
</div>
<div class="nprotagonistas__content aplicacion">
</div>
</div>
</div>
</div>
</div>
That is, only one of the class "nprotagonistas__bg" has to have the class "hover" randomly.
I don't really understood what you really want, but, here's a solution to achieve your task when the page is loaded.
So, when the page is loaded, we fetch all the divs containing the class nprotagonistas__bg and then randomly we'll assign the class hover to only one of the divs. This will be done depending on the number of divs containing the class nprotagonistas__bg and we'll use the built-in random method to get a random number that will be used as the index of the selected div(the random number is the index on the page of the div that's selected to get the hover class, so reloading the page ends in getting another random div).
With all that being said, here's a snippet to illustrate:
In the snippet, the hoverclass adds a red background to the element that has this class.
// waiting till the page is loaded by listening to the 'load' event on the 'window' object.
window.addEventListener('load', function() {
/**
* fetch all the divs with the class 'nprotagonistas__bg'.
* getting the number of these divs on the page(how many div is there).
* using the 'random' method we'll get a random number that is >= 0 and <= the number of the divs.
**/
var divs = document.querySelectorAll('div.nprotagonistas__bg'),
l = divs.length,
r = Math.ceil(Math.random() * l) - 1;
// assign the 'hover' class to a div depending on thethe random number.
divs[r].classList.add('hover');
});
.nprotagonistas__bg {
/* just to make the divs visible on the page */
height: 50px;
border: 2px solid green;
}
.nprotagonistas__bg.hover{
background: red;
}
<div class="nprotas">
<div class="container">
<div class="row">
<div class="col-6">
<div class="nprotagonistas">
<div class="nprotagonistas__bg grey">
</div>
<div class="nprotagonistas__content lectores">
</div>
</div>
</div>
<div class="col-6">
<div class="nprotagonistas">
<div class="nprotagonistas__bg white">
</div>
<div class="nprotagonistas__content controladores">
</div>
</div>
</div>
<div class="col-6">
<div class="nprotagonistas">
<div class="nprotagonistas__bg black">
</div>
<div class="nprotagonistas__content videointercomunicacion">
</div>
</div>
</div>
<div class="col-6">
<div class="nprotagonistas">
<div class="nprotagonistas__bg red">
</div>
<div class="nprotagonistas__content aplicacion">
</div>
</div>
</div>
</div>
</div>
Learn more about the random method.
Learn more about the ceil method.
Learn more about the addEventListener method.
Hope I pushed you further.
document.addEventListener('DOMContentLoaded', function(){
var elements = document.querySelectorAll(".nprotagonistas__bg");
var numberOfElements = elements.length;
var randomIndex = Math.floor(Math.random()*numberOfElements) + 1;
var current = elements[randomIndex];
current.classList.add('hover');
/* console.log('test'); */
});
You can improve it by triggering it when some event happened on your website like a click, a mouse hover, and so on and so though.
and to be sure that the .hover class is only on one element after the event is trigger because that event can be triggered many time
for example a click event on the body, within the event handler you select all the .nprotagonistas_bg and remove the hover
var elements = document.querySelectorAll(".nprotagonistas__bg");
elements.foreEach(function(element){
element.classList.remove('hover')
});
after that you can generate again a randomIndex and add the hover class to the corresponding element

Protractor, how to get an element if others classes have the same classname

I'm using Protractor with Cucumber for my tests, but I can't get an element cause the classname is the same of others classes and it don't have other attribute.
How can i get this element?
The element is: "tileGrid content".
I can't use xpath cause the page is edited sometimes.
Here my html:
<div class="tileGrid content">
<div class="spacing-container undefined">
<div class="title">
<h3 class="h2 heading">External Services</h3>
</div>
</div>
</div>
Thank you for your help.
I'm imagining your structure to be something similar to:
<div>
<div class="tileGrid content">
<div class="spacing-container undefined">
<div class="title">
<h3 class="h2 heading">External Services</h3>
</div>
</div>
</div>
<div class="tileGrid content">
<div class="spacing-container undefined">
<div class="title">
<h3 class="h2 heading">Other Header</h3>
</div>
</div>
</div>
<div class="tileGrid content">
<div class="spacing-container undefined">
<div class="title">
<h3 class="h2 heading">Another Header</h3>
</div>
</div>
</div>
...
</div>
There are a few ways you could interact with something like this, but I'll give just 3 examples:
This will look for the first child with the div tag within its parent
by.css('div div.content:nth-of-type(1)')
This will look for the first child with any tag within its parent
by.css('div div.content:nth-child(1)')
This will look for the text inside the h3 tag, and will select the element 3 layers above it:
by.xpath('//*/h3[text()="External Services"]/../../..')
Or find a DIV which includes a H3 and the H3's text is External Services as following:
by.xpath('//div[contains(#class, "tileGrid")][.//h3[text()="External Services"]]')

how do toggleClass in jquery?

I has example code html
<div class="new">
<div class="wrapper">
<div class="icon"></div>
<div class="content">content</div>
</div>
<div class="list"></div>
<div class="wrapper">
<div class="icon"></div>
<div class="content">content</div>
</div>
<div class="list"></div>
</div>
updated: I want when click to class icon in wrapper first toggle class list first . And class list second not change. Many thanks
$('.icon').click(function(){
$(this).next('.content').toggle('slow')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="new">
<div class="wrapper">
<div class="icon">QWE</div>
<div class="content">content</div>
</div>
<div class="wrapper">
<div class="icon">QWE</div>
<div class="content">content</div>
</div>
</div>
Use .next()
Description: Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.
Or .siblings()
Description: Get the siblings of each element in the set of matched elements, optionally filtered by a selector.

Nanoscroll doesn't support multiple contents

I'm using Tabulous.js script with NanoScroll.js
Here is my code :
<div id="tabs_container" class="nano">
<div id="tabs-1" class="overthrow content">
short text
</div>
<div id="tabs-2" class="overthrow content">
very long text
</div>
</div>
and
<script type="text/javascript">
$(function () {
$(".nano").nanoScroller({scroll: 'top'});
}
</script>
As the first content is short, nano is not used, but for the second content, it should appears.
Content is a class, that's why I though we could use multiple contents. Am I wrong ?
Any advises on this ?
Thanks in advance
You have only one "nano" class but two content classes.
For every scrolling on your page, you need two of the both classes.
So you may need something like this:
<div id="tabs_container" class="nano">
<div id="tabs-1" class="overthrow content">
short text
</div>
</div>
<div id="tabs_container_2" class="nano">
<div id="tabs-2" class="overthrow content">
very long text
</div>
</div>
Or somethink like this:
<div id="tabs_container" class="nano">
<div class="content">
<div id="tabs-1" class="overthrow">
short text
</div>
<div id="tabs-2" class="overthrow">
very long text
</div>
</div>
</div>

Categories