Find element that has no direct children with specific class - javascript

In a page of HTML elements, I am trying to find a parent element with class .dmc that does not contain a direct child element with a specific class .dynamic, using JQuery.
I have tried:
$('.dmc:not(:has(.dynamic))')
However this checks all descendants, and I only want to check the first level of descendants.
I think there is a very simple answer, but I can't quite come up with it. Any help appreciated!

Since :has is already jQuery-specific, you could use an unrooted >, which jQuery's Sizzle selector engine seems to support:
$(".dmc:not(:has(> .dynamic))").addClass("green");
// --------------^
$(".dmc:not(:has(> .dynamic))").addClass("green");
.green {
color: green;
font-weight: bold;
}
<div class="dmc">1</div>
<div class="dmc">2
<div class="dynamic">dynamic</div>
</div>
<div class="dmc">3</div>
<div class="dmc">4
<div class="dynamic">dynamic</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
But I'd be slightly worried about it, and would probably go for filter instead:
$(".dmc").filter(function() {
return $(this).children(".dynamic").length == 0;
}).addClass("green");
$(".dmc").filter(function() {
return $(this).children(".dynamic").length == 0;
}).addClass("green");
.green {
color: green;
font-weight: bold;
}
<div class="dmc">1</div>
<div class="dmc">2
<div class="dynamic">dynamic</div>
</div>
<div class="dmc">3</div>
<div class="dmc">4
<div class="dynamic">dynamic</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

Related

Insert wrapper around div without an ID or class

I'm trying to insert a wrapper around two divs, one with a dynamically generated ID. The div with the random ID is dynamically generated. No matter what I try, the wrapper is getting inserted after the target div though.
Before wrapper
<div id="search">Search</div>
<div id="234234">Unknown</div>
<div id="list">List</div>
After wrapper
<div id="search">Search</div>
<div id="wrapper">
<div id="234234">Unknown</div>
<div id="list">List</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="search">Search</div>
<div id="wrapper">
<div id="234234">Unknown</div>
<div id="list">List</div>
</div>
EDIT
I have decided to use CSS to reposition the elements so that I no longer need the wrapper.
Simply wrap the children!
$("#wrapper").children().wrapAll("<div class='wrapper'/>")
#wrapper { padding: 20px; }
.wrapper { background-color: gold; outline: 2px solid red; }
<div id="wrapper">
<div id="123456">has whatever ID</div>
<div id="list">has id</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Or, to target elements that actually have any ID attribute use the "[id]" selector:
$("#wrapper").children("[id]").wrapAll("<div class='wrapper'/>")
#wrapper { padding: 20px; }
.wrapper { background-color: gold; outline: 2px solid red; }
<div id="wrapper">
<div id="list123456">has id</div>
<div id="list">has id</div>
<div>Foo bar</div>
<div id="list234">has id</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Before Edit:
Use the :not([id]) or / and [id=""] selectors if you want to target "no ID attribute" / or / "empty ID attribute" respectively:
$("#wrapper").children("div:not([id]), div[id='']").wrap("<div class='wrapper'/>")
#wrapper { padding: 20px; }
.wrapper { background-color: gold; outline: 2px solid red; }
<div id="wrapper">
<div id="">has no id</div>
<div>has no attribute id</div>
<div id="list">has id</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
If you do not know the element id, you can still use a class attribute to access it. Give the element with the random id (and any other elements you want to move) a class attribute so you can access via JavaScript and manipulate the DOM. You can do it simply with no jQuery, like this:
// Create the `div.wrapper` element
const wrapperEl = document.createElement('div');
wrapperEl.classList.add('wrapper');
// Create a reference to each element you want to make a child of `div.wrapper`
const childEls = document.querySelectorAll('.wrapped');
// Move the elements from `body` to `div.wrapper` parent
wrapperEl.replaceChildren(...childEls);
// Append the `div.wrapper` to the body element
const bodyEl = document.querySelector('body')
bodyEl.appendChild(wrapperEl);
console.log(wrapperEl.outerHTML);
<div id="search">Search</div>
<div id="234234" class="wrapped">Unknown</div>
<div id="list" class="wrapped">List</div>
I've logged the wrapperEl HTML in the console, but you can also inspect the HTML in your dev tools "Elements" tab to see the wrapper.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/replaceChildren#transferring_nodes_between_parents

Is it possible to remove an html element and keep your children with javascript?

I have the following structure .. I would like to remove div.son but keepdiv.grandson, is that possible ?! or changing your <tag> would also be a solution .. ex: changing from <fieldset> to a <div>, remembering that I do not have access to HTML, every change must be done using ** javascript **!
<div class="father">
<fieldset class="son">
<div class="grandson">Content here</div>
<div class="grandson">Content here</div>
<div class="grandson">Content here</div>
<div class="grandson">Content here</div>
</fieldset>
</div>
I tried to use the removeChild () function of ** javascript **, but it removes the entire element.
It's possible with vanilla JavaScript by deep cloning the node of grandson before removing anything else. and then appending it back to the parent. Of course if you want to place it somewhere else, you need to append needed logic of DOM traversing. (CSS section is only for visual validation of the result)
const grandson = document.querySelector('.grandson');
const father = grandson.closest('.father');
const clonedGrandson = grandson.cloneNode(true);
father.querySelector('.son').remove();
father.appendChild(clonedGrandson);
.father {
background-color: red;
padding: 20px;
}
.son {
background-color: blue;
padding: 20px;
}
.grandson {
background-color: green;
padding: 20px;
}
<div class="father">
<fieldset class="son">
<div class="grandson">
<p>Save me</p>
</div>
</fieldset>
</div>
You may take a look at this answer, try to use the search bar next time.
https://stackoverflow.com/a/170056/10944905
In case you just want to jump all over the answer.
var cnt = $(".remove-just-this").contents();
$(".remove-just-this").replaceWith(cnt);

how to add a class to parent child of a div

<div class="parent">
<div class="child-class">
<div>
<div class="child-class">
<div>
<div class="child-class">
<div>
</div>
I need to add a class to second child-class using jQuery
Adress the second child of the parent via CSS Selector:
$('.parent > .child-class:nth-of-type(2)').addClass('your-class');
Advantage over using nth-of-type instead of nth-child is beeing more precise in selecting what you want. The nth-child will select any child of your parent. nth-of-type will only select children with a certain type (in this case class child-class).
You can use :nth-child selector at this context,
var elem = $(".parent > .child-class:nth-child(2)");
Note that, the index that is being passed into the selector would start from 1 not from 0.
Here you go with a solution
$('.parent > .child-class:eq(1)').addClass('newClass');
.child-class {
width: 100px;
height: 50px;
border: 1px solid;
}
.newClass {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="child-class"></div>
<div class="child-class"></div>
<div class="child-class"></div>
</div>
I've used jQuery eq selector.
Documentation: https://api.jquery.com/eq-selector/
Hope this will help you.

how to change the attributes of child divs from the parent div through javascript?

#va{
color:yellow;
}
#v{
color:pink;
}
<div id = "va">
<div id ="v">my name is </div>
<div>khan</div>
</div>
i have tried using document.getelementbyid("va").style.color="yellow"; but the color of element v is not changing i want to change its color by the id of parent i want it to be done through javascript as it is the simple example of the situation in which i am traped plz help
$("#va>#v").css("background-color","green")
#va{
color:yellow;
}
#v{
color:pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = "va"> asdasd
<div id ="v">my name is </div>
<div>khan</div>
</div>
Use > the direct child selector.
The selector will select the direct child(with id v) of element with id va and change color to red
With jquery you have two options, using the .children() method or using .find() method, take a look in this snippet:
$("#va").children().css("color", "red");
//$("#va").find("#v").css("color","blue");
#va {
color: yellow;
}
#v {
color: pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="va">
<div id="v">
my name is
</div>
<div>
khan
</div>
</div>
If you want to change the color of ID v, use getElementById("v") rather that getElementById("va")
document.getElementById("v").style.color = "yellow";
#va {
color: yellow;
}
#v {
color: pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="va">
<div id="v">my name is </div>
<div>khan</div>
</div>
you can change the class attribute of any element and create the css to what you need using:
document.getElementById("va").setAttribute("class", "yellow-class");
css would bw something like:
.yellow-class{
color: yellow;
}
Colors styles only affect child nodes if the child node's color property is set to initial.
#va{
color:yellow;
}
#v{
color:initial;
}
However, this will remove the default pink color from your tag. There are lots of different ways you could solve this problem but the simplest would be to just create a new style rule and simply use js to add a class to #va to change the style.
#va.yellow #v {
color: yellow;
}
And use this js.
document.getElementById("va").className += " yellow";

Javascritpt change class to a div near to his grand-father

I want to dynamically change the class of the element #sidePanel from .compact to .expanded, in this code:
<div id="sidePanel" class="compact"></div>
<div id="topbar">
<div id="buttonContainer">
<div id="button"></div>
</div>
</div>
I'm stuck here, I can't apply the class to the correct <div>, I can just add the class to the topbar:
$(document).ready(function(){
$("#button").mouseover(function(){
$("this").parent().eq(2).addClass(".expanded").removeClass(".compact");
});
});
I also tried this:
$(document).ready(function(){
$("#button").mouseover(function(){
$("#sidepanel").addClass(".expanded").removeClass(".compact");
});
});
Your second example was pretty close. When you $.addClass() and $.removeClass(), or are referring to classnames outside of using a selector to target something, just reference the class name (no need for the leading .). Also JS (and CSS) are case-sensitive, so $('#sidepanel') won't target #sidePanel - the cases need to match.
$("#button").mouseover(function() {
$("#sidePanel").addClass("expanded").removeClass("compact");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>.expanded {color: red;}</style>
<div id="sidePanel" class="compact">sidepanel</div>
<div id="topbar">
<div id="buttonContainer">
<div id="button">button</div>
</div>
</div>
In your first example, $(this) is how you reference this in jQuery. If you put this in quotes, the word this is treated as a string literal instead. And since to use $.parent() you would need to go up 2 levels, you should use $.parents() with the ID of the parent you want to target, then use $.prev() to select the previous element, which is #sidePanel. So to traverse the DOM like that, this is how I would do it.
$("#button").mouseover(function() {
$(this).parents('#topbar').prev().removeClass('compact').addClass('expanded');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>.expanded {color: red;}</style>
<div id="sidePanel" class="compact">sidepanel</div>
<div id="topbar">
<div id="buttonContainer">
<div id="button">button</div>
</div>
</div>
Your problem is you used $("#sidepanel") instead of $("#sidePanel")
Here's a working example after the change is made:
$(document).ready(function(){
$("#button").on('mouseover', function(){
$("#sidePanel").addClass("expanded").removeClass("compact");
});
});
#topbar > div {
width: 100px;
height: 30px;
background: #ccc;
margin-top: 20px;
}
#sidePanel {
width: 100%;
height: 40px;
background: #ccc;
}
#sidePanel.expanded {
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sidePanel" class="compact"></div>
<div id="topbar">
<div id="buttonContainer"></div>
<div id="button"></div>
</div>
first: the solution
$(document).ready(function()
{
$("#button").mouseover(function()
{
// class names - without the dot
$("#sidepanel").addClass("expanded").removeClass("compact");
});
});
then: why you were really close on your first attempt
$(document).ready(function()
{
$("#button").mouseover(function()
{
// $(this) selector uses the `this` keyword (not as a string)
$(this).parent().eq(2).addClass(".expanded").removeClass(".compact");
});
});

Categories