So I have the following divs
<div id="az" class="d_1" value="data1"></div>
<div id="az" class="d_2" value="data2"></div>
<div id="by" class="d_3" value="data3"></div>
<div id="az" class="d_4" value="data4"></div>
how can I check only if az divs are clicked without adding onClick="reply_click(this)" to every div?
Delegation is what you want after swapping ID and class and using data attributes because IDs need to be unique and DIVs do not have value
window.addEventListener("load",function(){ // on page load
document.getElementById("container").addEventListener("click",function(e) { // clicking anything in container
const tgt = e.target; // the event target (what was clicked)
if (tgt.classList.contains("az")) { // ignore click on "by"
console.log("az clicked", tgt.dataset.value)
}
})
})
<div id="container">
<div class="az" id="d_1" data-value="data1">D1</div>
<div class="az" id="d_2" data-value="data2">D2</div>
<div class="by" id="d_3" data-value="data3">D3</div>
<div class="az" id="d_4" data-value="data4">D4</div>
</div>
id attribute must always be unique:
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id
You have your class and id attributes structured the opposite of what they should be. class can be non-unique to refer to a group of elements.
Below is a sample of how you can use addEventListener and the class css selector to achieve what you asked for.
function reply_click(){
console.log(this.getAttribute('value'));
}
document.getElementsByClassName('az').forEach( el => el.addEventListener('click',reply_click) );
<div class="az" id="d_1" value="data1">1</div>
<div class="az" id="d_2" value="data2">2</div>
<div class="by" id="d_3" value="data3">3</div>
<div class="az" id="d_4" value="data4">4</div>
Related
I have a Div element on my HTML page, and that DIV is coming from an ASP.NET application, so the DIV ID is changing all the time but few words remain the same in that id.
For example:
<div id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00__UWT_ctl01_ctl00_ctl04
_NewGrid"> </div>
The only things which remains same all the time in above example are "_UWT" & "_NewGrid".
I know how to get the by Exact ID or atleast by using the 1 word in this: $( "div[id$='_UWT']" )
But I need to get this Div element by using the multiple parameters:
I need to check the "_UWT" and "_NewGrid" also.
If both words exist in the Div id, then return me the element only.
I need to get this DIV by JQuery.
I know I can set the ClientID to Static from ASP.NET, but that is not doable in my case.
Thanks.
To achieve this you can combine the 'attribute contains' selector (to find the _UWT) and the 'attribute ends with' selector (to find the _WebGrid), like this:
$('div[id*="UWT"][id$="_NewGrid"]').addClass('foo');
.foo {
color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00_ctl01_ctl00_ctl04_NewGrid">Not this one</div>
<div id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00__UWT_ctl01_ctl00_ctl04">Not this one</div>
<div id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00__UWT_ctl01_ctl00_ctl04_NewGrid">This one</div>
One way could be:
$('div').each(function() {
if($(this).attr('id').includes('_NewGrid') && $(this).attr('id').includes('_UWT')) {
console.log($('div').attr('id'));
$(this).css('color','red') // do whatever you want with div
}
})
Demo:
$('div').each(function() {
if($(this).attr('id').includes('_NewGrid') && $(this).attr('id').includes('_UWT')) {
console.log($('div').attr('id'));
$(this).css('color','red')
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00__UWT_ctl01_ctl00_ctl04
_NewGrid">11111</div>
<div id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00__UWT_ctl01_ctl00_ctl04
_NewGri">222222222</div>
<div id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00__ctl01_ctl00_ctl04
_NewGrid">3333333333333</div>
Try following way:
Add specific class I added here item-collection:
<div class="item-collection" id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00__UWT_ctl01_ctl00_ctl04
_NewGrid">Div 1</div>
<div class="item-collection" id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00__UWT_ctl01_ctl00_ctl04">Div 2</div>
<div class="item-collection" id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00_ctl01_ctl00_ctl04
_NewGrid">Div 3</div>
<div class="item-collection" id="ctl00_ctl00_MainContent_DetailBody_ctl01_ctl02_ctl00_ctl01_ctl00_ctl04
_NewGrid">Div 4</div>
JS is:
var itemslist = [];
$(".item-collection").each(function(){
if($(this).attr("id").indexOf("_UWT") > -1 && $(this).attr("id").indexOf("_NewGrid")){
itemslist.push($(this))
}
})
console.log(itemslist);
I'm using the liferay framework and I need to add a JavaScript detected inline height to a very very specific div in my page. The problem is I need to target it going through an unknown number of dynamically added divs with dynamically added classes and IDs. To complicate this even further, the divs are randomly siblings or nested in each other.
Here's what it looks like:
<div class="known-class">
<div class="unknown dynamicallygenerated"></div>
<div class="unknown dynamicallygenerated">
<div class="unknown dynamicallygenerated">
<div class="unknown dynamicallygenerated"></div>
<div class="unknown dynamicallygenerated">
<div class="DIV-I-WANT-TO-TARGET">this is the div i need to Target with my css/javascript</div>
</div>
</div>
</div>
obviously I can't target it simply with
function resize() {
var heights = window.innerHeight;
jQuery('.DIV-I-WANT-TO-TARGET').css('height', heights + "px");
}
resize();
Because that class is present elsewhere, I would rather target it with something like.
jQuery('.known-class .DIV-I-WANT-TO-TARGET')
Which obviously doesn't work because there's a ton of other divs in the middle and my div is not a child of ".known-class"
I was asking myself if there was any jQuery that could help. Something like:
Catch any div with .DIV-I-WANT-TO-TARGET class that is "generically" inside another div that has .known-class
Is this possible? thanks a lot for your help!
Something like this would work:
// this will target the known-class and find all children with DIV-I-WANT-TO-TARGET
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET');
// this will target the known-class and find the first DIV-I-WANT-TO-TARGET
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET').first();
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET:first');
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET:eq(0)');
$('div.known-class').find('div.DIV-I-WANT-TO-TARGET').eq(0);
You can try in your css file
.known-class div div div div{}
The last div being the DIV-I-WANT-TO-TARGET
Assuming that you are adding the divs starting from the outer to the inner
Assign an equal name plus a number starting from 1
<div class="known-class">
<div class="unknown dynamicallygenerated" id="dynamicdiv1"></div>
<div class="unknown dynamicallygenerated" id="dynamicdiv2">
<div class="unknown dynamicallygenerated" id="dynamicdiv3">
<div class="unknown dynamicallygenerated" id="dynamicdiv4"></div>
<div class="unknown dynamicallygenerated" id="dynamicdiv5">
<div class="DIV-I-WANT-TO-TARGET" id="dynamicdiv6"></div>
</div>
</div>
</div>
The use jQuery [.each][1] to loop through all the divs on the document
$( document.body ).click(function() {
$( "div" ).each(function( i ) {
if ( this.style.color !== "blue" ) {
this.style.color = "blue";
} else {
this.style.color = "";
}
});
});
When you reach the last item in numeric order. (you can use any split function) add the attributes to that div
you need to select last div inside the known-class:
$('.known-class').find('div:last').css('background', 'Red')
OR if you want to select all the .known-class :
$('.known-class').each(function() {$(this).find('div:last').css('background', 'Red')});
Actually your selector works just fine:
$('.known-class .DIV-I-WANT-TO-TARGET')
With a space, selectors will find any descendant.
The search is only limited to direct descendants (immediate children) if you use the > operator.
So $('.known-class > .DIV-I-WANT-TO-TARGET') would not find what you wanted.
I just need to access the parent div where I have a button changing his siblings divs.
A code example can explain better:
<div class="parent"> <!-- This is structure repeats N times -->
<div class="divToToggleVisiblity divA">trololo A</div>
<div class="divToToggleVisiblity divB">trololo B</div>
<button onClick="toggleThem(this)">This button will toggle above divs</button>
</div>
function toggleThem(a){ // something like this, BUT without Jquery
$(a).closest(".parent").find(".divA").hide();
}
That's what parentNode is for:
a.parentNode.querySelectorAll('.divA');
function toggleThem(elem) {
elem.parentNode.getElementsByClassName('divA')[0].style.display = 'none';
}
I was wondering how you could "relate" two HTML elements.
For example, let's say a user clicks on a selection item and I want the element "related" to that element disappear.
<div id="game1Selection">I pick team1</div>
<div id="game2Selection">I pick team2</div>
<div id="game1">This is game 1</div>
<div id="game2">This is game 2</div>
What I would want to happen is that when a user selects "game1Selection" that the div "game1" will disappear and the same thing for game2, game3, etc. I know how to do this the long way:
$('#game1Selection').click( function() {
$('#game1').toggleClass('selected');
}); //selected has the attribute display:none
How could I make two of them related so I don't have to write it the long way and just use this
jsBin demo
$('div[id$=Selection]').click(function(){
var myID = this.id.split('Selection')[0];
$('#'+myID).toggleClass('selected');
});
use the ends with selector $ and retrieve the first part of the ID name by splitting the original ID and getting the first ([0]) part of the name (gameN)
a better idea demo
But a far better example would be using this HTML:
<div>
<div class="selection">I pick team1</div>
<div class="selection">I pick team2</div>
</div>
<div class="game">This is game 1</div>
<div class="game">This is game 2</div>
and retrieve the clicked element index() and find the matching element using .eq() :
$('.selection').click(function(){
var i = $(this).index();
$('.game').removeClass('selected').eq(i).addClass('selected');
});
This will allow you to remove the already selected classes and assign it to the index-matching element.
Use classes for like behavior, and grab the number from the id.
<div id="game1Selection" class="selection">I pick team1</div>
<div id="game2Selection" class="selection">I pick team2</div>
<div id="game1" class="game">This is game 1</div>
<div id="game2" class="game">This is game 2</div>
$('.selection').click( function() {
$("#" + this.id.replace("Selection", "")).toggleClass('selected');
$('.game').not(this).removeClass('selected');
});
I prefer to use HTML5's data-* properties to make the association more explicit:
<div class="selector" data-fadetarget="game1">I pick team1</div>
<div class="selector" data-fadetarget="game2">I pick team2</div>
<div id="game1">This is game 1</div>
<div id="game2">This is game 2</div>
JavaScript:
$('.selector').click( function() {
var target = '#' + $(this).data('fadetarget');
$(target).toggleClass('selected');
});
Using this method, the associations are explicit in the markup and won't fail if things are rearranged.
I'm adding a click event to a span that is within a div. The target of this event, which will become visible, is a first div that is within a div, two divs down. How can I traverse the DOM to find it?
Perhaps it'll be clearer with the code:
<div a>
<h2>
<span id="here">Click</span>
</h2>
</div>
<div></div>
<div>
<div class="targetDiv">This is the div we need to find</div>
<div class="targetDiv">There are other divs with the same id, but we don't need to find those</div>
<div class="targetDiv">Not looking for this one </div>
<div class="targetDiv">Or this one either</div>
</div>
I've searched left and right and cannot find an answer. It's important to restrict the event ONLY to the first div immediately after the span.
Any help would be much appreciated.
As shown, the code would look like this:
$('span#here').on('click', function() {
$(this).closest('div').siblings(':contains(.targetDiv)').children().eq(0).show();
}
Here's a sample of the fish we caught
$(function() {
$('#here').on('click', function() {
var div = $(this) //the element clicked
.closest('div') //find nearest parent div
.nextAll(':eq(1)') //find the second next div
.children(':eq(0)') //find the first child of it
.show(); //remove invisible cloak
});
});
This works. I provided an example you can just save to a html file and test it yourself
<style>
.targetDiv{display:none;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#here').click(function(){
$('.targetDiv').first().show(); // or whatever you want
});
});
</script>
<div a>
<h2>
<span id="here">Click</span>
</h2>
</div>
<div></div>
<div>
<div class="targetDiv">This is the div we need to find</div>
<div class="targetDiv">There are other divs with the same id, but we don't need to find those</div>
<div class="targetDiv">Not looking for this one </div>
<div class="targetDiv">Or this one either</div>
</div>