This question already has answers here:
JavaScript next sibling?
(2 answers)
Closed 9 years ago.
I have a div which contains other divs like this:
<div id="main_div">
<div id="div_1">
<div id="some_id"></div>
</div>
<div id="div_2">
<div id="some_id"></div>
</div>
<div id="div_3">
<div id="some_id"></div>
</div>
</div>
How can programatically get the next div id when a particular div is clicked?
div_1 is clicked -> alert div_2
div_2 is clicked -> alert div_3
Thanks
If you can use jQuery, you should do it like this.
Using the next function
$("#main_div > div").on("click", function(){
alert($(this).next("div").attr("id"));
});
You coud use Node.nextSibling
Returns the node immediately following the specified one in its parent's childNodes list, or null if the specified node is the last node in that list.
var div = document.getElementById('main_div');
for (var i=0, len=div.children.length; i<len; i++) {
div.children[i].addEventListener('click', function(e) {
var nextSib = e.target.nextSibling;
if (nextSib) alert(nextSib.id);
}, false);
}
Related
This question already has answers here:
Find HTML based on partial attribute
(2 answers)
Closed 1 year ago.
<div data-start-one="one"></div>
<div data-start-one="one"></div>
<div data-start-two="two"></div>
<div data-start-three="three"></div>
How can I retrieve all elements that have a jQuery attribute that starts with data-start?
For example: $("div[data-start-*]")
There's no good way to do this. You'll have to iterate over all elements that might match what you want, then filter them out.
const starts = $('div').filter(function() {
return [...this.attributes].some(
attrib => attrib.name.startsWith('data-start')
);
});
console.log(starts.length);
console.log(starts[3]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-start-1="one"></div>
<div data-start-1="one"></div>
<div data-start-2="two"></div>
<div data-start-3="three"></div>
<div class="somethingElse"></div>
A much better approach would be to be able to select these elements using something else in common, like a class or another data attribute or a descendant of a container.
const starts = $('.container div');
console.log(starts.length);
console.log(starts[3]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div data-start-1="one"></div>
<div data-start-1="one"></div>
<div data-start-2="two"></div>
<div data-start-3="three"></div>
</div>
<div class="somethingElse"></div>
I have this HTML code (and the number of components that I want to edit it's variable, it could be 3 or 20).
I have created a small example with similar scenario on my website
As you can see my script is able to edit the father div and add the classname. Same for firstchild.
I would like to edit all divs inside firstchild but not the immediately div, it has to be two inside.
Any ideas why my code is not working on the last part?
Thanks.
// WORKS OK
var firstc = document.getElementById('father');
firstc.classList.add("father-class");
firstc.children[0].children[0].children[0].setAttribute("id", "firstchild"); // WORKS OK
var second = document.getElementById('firstchild');
second.classList.add("child-class");
// NOT WORKING
var grandchildren = second.children[0].children[0].children[0];
for (let z = 0; z < grandchildren.length; z++) {
grandchildren[z].classList.add("slide");
}
<div id="father">
<div>
<div>
<div id="firstchild">
<div>
<div>
<div class="random63637236">
<li>1</li>
</div>
<div class="generic">
<li>2</li>
</div>
<div class="italy_gdgd">
<li>3</li>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
the problem in your code is the last children[0]. you are selecting only the first div, it's not an array. Fix that line and everything will work
var grandchildren = second.children[0].children[0].children;
As a side note: if for some reason the first or the second .children[0] are undefined you will get an error.
A better approach is to use querySelectorAll which returns an array;
if your array it is empty, nothing happens.
second.querySelectorAll('#firstchild > div > div > div')
.forEach(el => el.classList.add('slide'))
I do not have access to jquery. I'm trying to implement an accordion, but the content element is not immediately after the header. It is something similar to the following:
<div class="header">...</div>
<div>
<div class="content">
So I'm adding a function to handle an onclick event on the header, which needs to then obtain the next element in the HTML source code that has the content class. How can I achieve that?
You can achieve this using querySlector on the clicked header node
<div class="header">
<div>
<div class="content">
[].forEach.call(document.querySelectorAll('.header'), function(header) {
header.addEventListener('click', function(e) {
var content = this.querySelector('.content');
// here, "this" is the header div, and "content" is the content div
// do majick accordion things here
});
});
How about using recursive function and nextSibling [get next element (not children)]
<div class="header" onclick="hasClass(this)">...</div>
<div>
<div class="content"></div>
</div>
<script>
function hasClass(e){
if(e.nextSibling.children === undefined || e.nextSibling.children.length == 0){
hasClass(e.nextSibling); //go next till find class
}
else{
if(e.nextSibling.children[0].className == "content"){
console.log(e.nextSibling.innerHTML); //get class content html
}
}
}
</script>
You can get this by
var contentDiv= document.getElementsByClassName("content");
try this document.getElementById(header).getElementsByClassName('content');
I have a function that assigns dynamic classes to my div's. This function is a that runs on the page. After the page loads, all 10 of my primary 's have classes ".info1" or ".info2" etc...
I am trying to write a Jquery function that changes the class of the div you click on, and only that one. Here is what I have attempted:
$(".info" + (i ++)).click(function(){
$(".redditPost").toggleClass("show")
});
I have also tried:
$(".info" + (1 + 1)).click(function(){
$(".redditPost").toggleClass("show")
});
And
$(".info" + (i + 1)).click(function(){
$(".redditPost").toggleClass("show")
});
EDITED MY HTML: DIV RedditPost is actually a sibling to Info's parent
<div class="listrow news">
<div class="newscontainer read">
<div class=".info1"></div>
<div class="redditThumbnail"></div>
<div class="articleheader read">
</div>
<div class="redditPost mediumtext"></div>
</div>
My issue is two fold.
The variable selection for ".info" 1 - 10 isn't working because i doesn't have a value.
If I did target the correct element it would change all ".redditPost" classes instead of just targeting the nearest div.
Try like this.
$("[class^='info']").click(funtion(){
$(this).parent().find('.redditPost').toggleClass("show");
});
Alternative:
$('.listrow').each(function(){
var trigger = $(this).find("[class^='info']");
var target = $(this).find('.redditPost');
trigger.click(function(){
target.toggleClass("show");
});
});
Try this
$("div[class*='info']").click(function(){
$(this).parent().find(".redditPost").toggleClass("show")
});
Explanation:
$("div[class*='info'])
Handles click for every div with a class containing the string 'info'
$(this).parent().find(".redditPost")
Gets the redditPost class of the current clicked div
Since the class attribute can have several classes separated by spaces, you want to use the .filter() method with a RegEx to narrow down the element selection as follows:
$('div[class*="info"]').filter(function() {
return /\binfo\d+\b/g.test( $(this).attr('class') );
}).on('click', function() {
$(this).siblings('.redditPost').toggleClass('show');
});
.show {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="listrow news">
<div class="newscontainer read">
<div class="info1">1</div>
<div class="redditThumbnailinfo">2</div>
<div class="articleheader read">3</div>
<div class="redditPost mediumtext">4</div>
</div>
</div>
This question already has answers here:
Recursively change element type with jQuery, why it's partially working?
(2 answers)
Closed 7 years ago.
I'm trying to replace all the child elements in a certain element to DIVs.
I have the following structure:
<div id="wrapper">
<span>
<span>
<span>
<span></span>
<span></span>
</span>
</span>
</span>
</div>
I've tried replaceElements($('#wrapper')):
function replaceElements($element){
var children = $element.find("*");
var current;
for(var i=0; i<children.length; i++){
current = $(children[i]);
current.replaceWith("<div>" + current.html() + "</div>");
}
}
However this doesn't work because when it tries to change the N+1 element it all ready doesn't exist because it was replaced when doing the Nth element. N+1 is a descendant of N and thus is being changed when changing the .html() of N. Preserving element attributes is not an issue here.
How can I change all the child SPANs into DIVs, please?
You should not use the html content in the replaced element, instead need to add the dom elements to it
function replaceElements($element) {
$element.find("*").replaceWith(function() {
return $('<div></div>', {
html: this.childNodes
});
})
}
replaceElements($('#wrapper'))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="wrapper">
<span>1
<span>2
<span>3
<span>4</span>
<span>5</span>
</span>
</span>
</span>
</div>
Note: No attributes of the elements will be copied