Fire jQuery if parent lose class - javascript

I've got a simple Image-Slider (Flexslider 2 based on jQuery) on my website. If an element gets active, the element gets the class called "active-slide".
If this happen, the child should get the class "show". If the parent lose the class, the child should lose its class as well.
My current script is not working:
$( ".flexslider .slides li" ).change(function() {
$( ".child" ).toggleClass("show");
});
HTML CODE
<ul class="flexslider">
<li class="">
<img src="http://www.placehold.it/400x100">
<div class="flax-caption">Lorem Ipsum</div>
</li>
<li class="active-slide">
<img src="http://www.placehold.it/400x100">
<div class="flax-caption">Lorem Ipsum</div>
</li>
</ul>

Related

Getting click event from parent container except certain children

Expected behavior: When I click on the .parent class, an item detail modal will be shown but the modal won't be shown if I click on the .dropdown or any of it's option.
<div class="parent click-for-item-detail">
<div class="dropdown">
Options
<ul class="dropdown-menu">
<li>option-1</li>
<li>option-2</li>
</ul>
</div>
<div class="item-image"><img class="click-for-item-detail" src="image.jpg></div>
<div class="info">
Item title
<div class="click-for-item-detail"> item subtitle</div>
</div>
</div>
So far:
$(".click-for-item-detail").on("click",function(e){
// show the modal if the target itself has been clicked
if(e.target === this) {
$('#itemDetailModal').modal('toggle');
}
});
I have added click-for-item-detail class in every element that should trigger the item detail modal. Is there a better way to achieve this?
It is true what Phong is saying and that works. However, imagine now you had many child elements in your parent all matching that selector. With something like below, you would add an event listener to each of those elements.
$(".info, .item-image").on("click", function(){
console.log("Trigger");
});
While with your first approach you were already very close to only have one listener, no matter how many child elements are in the parent.
Consider following example:
<ul class='parent'>
<li>No</li>
<li>Click</li>
<li>Event</li>
</ul>
$(".parent").on("click",function(e) {
if(!e.target.classList.contains('parent')) {
return console.log('no event')
}
console.log('fire event')
});
This is called event delegation, and you pretty much do this already. Here I am checking if the element, I am clicking on, is indeed of class parent, only then I fire my event.
You can of course do all sorts of checks, for example only the <li> elements.
$(".parent").on("click", (e) => e.target.tagName == 'LI' && console.log('fire event'))
Here check out this example https://codepen.io/bluebrown/pen/xxGVgYd?editors=1111
I would recommend doing a web search for event delegation and event bubbling.
You can specify some selectors to be able to trigger.
Read the following post to have a better understanding.
Event listener for multiple elements - jQuery
$(".info, .item-image").on("click", function(){
console.log("Trigger");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent click-for-item-detail">
<div class="dropdown">
Options
<ul class="dropdown-menu">
<li>option-1</li>
<li>option-2</li>
</ul>
</div>
<div class="item-image"><img class="click-for-item-detail" src="image.jpg"></div>
<div class="info">
Item title
<div class="click-for-item-detail"> item subtitle</div>
</div>
</div>
You can use :not() selector to filter out the element you do not to be clicked:
$('.parent > :not(.dropdown)').click(function(e){
alert('modal');
//show modal
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div class="dropdown">
Options
<ul class="dropdown-menu">
<li>option-1</li>
<li>option-2</li>
</ul>
</div>
<div class="item-image"><img src="image.jpg"></div>
<div class="info">
Item title
<div> item subtitle</div>
</div>
</div>

Changing html classes using jquery

I have many elements with the same class name such as:
<li class="contact" id="content">
// some content here....
</li>
.
.
<li class="contact active" id="content">
// some content here....
</li>
.
.
<li class="contact" id="content">
// some content here....
</li>
.
.
<li class="contact" id="content">
// some content here....
</li>
.
.
All the classes have the same name except for one which says 'contact active'.
This element in the page will be highlighted when the user clicks on it. I've wrote a jquery script to change the class name when clicked on here:
$('#content').click(function() {
$(this).removeClass('contact');
$(this).addClass('contact active');
});
But the problem is, it only searches for one matching id and then it stops. So, except for the first element all the other elements have no effect. Also I would like to change the name of the already active class ('contact active') back to just 'contact' when I click on the other elements.
IDs must be unique. Your id selector is assigning click event to only first element in matched set.
You need to modify the click event to have class selector and not ID Selector:
var $contactDiv = $('.contact');
$contactDiv.click(function() {
$contactDiv.removeClass('active'); // remove all active
$(this).addClass('active'); // add it back on this object
});
The main problem you have is that id attributes need to always be unique within the DOM. If you want to group elements with a common identifier, use a class.
You can then select the elements by that class and call toggleClass() on them. Note that you also don't need to remove/add the contact class either.
the last problem is there can be only one active class at a time so the other active class should get unselected.
In that case you can simply call removeClass() on all the .content elements but the one which was clicked. Try this:
$('.content').click(function() {
$('.content').not(this).removeClass('active');
$(this).toggleClass('active');
});
.active {
color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="content contact">
Content...
</li>
<li class="content contact active">
Content...
</li>
<li class="content contact">
Content...
</li>
<li class="content contact">
Content...
</li>
</ul>
$('.contact').click(function() {
$('.contact').removeClass('active');
$(this).addClass('active');
});
.active {
color: #000;
font-size:20px;
font-weight:700;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="contact">
Content 1...
</li>
<li class="contact">
Content 2...
</li>
<li class="contact">
Content 3...
</li>
<li class="contact">
Content 4...
</li>
</ul>
The main issue is id. id should be unique on a page. As you are using id="content" multiple times on a single page. Now you need to modify your jQuery as:
$('.contact').click(function() {
$('.contact').removeClass('active');
$(this).addClass('active');
});

How can I create an expression that evaluates whether or not a parent div's descendants are active?

Imagine I have a div with a few descendants/children as such:
<div id="parent" tabindex="0">
<h1 tabindex="0"> my Header </h1>
<p tabindex="0"> some text </p>
<ul tabindex="0">
<li tabindex="0"> item 1 </li>
<li tabindex="0"> item 2 </li>
<li tabindex="0"> item 3 </li>
</ul>
</div>
How can I create an expression that checks whether or not a child of the 'parent' div is active/has focus? I'd like to perform some action (ex: console log) if the statement evaluates to true.
I'd imagine it's go something like:
if( document.activeelement === <descendant of 'parent' div>) {
console.log("descendant is active");
}
EDIT: For clarity:
The evaluation should occur as an 'if' statement. The expression should translate like so:
if my active element has a parent with an id of 'parent' then do something.
do you know the id of the parent and the classnames of the children? or will these be dynamic based on what is clicked? if you know the selector of the parent and children, the following will grab an li element that is a deep or immediate child of the #parent element that is active. if it is empty, then none of those tabs are focused
$(#parent li:focus)
using this jquery selector, we're asking for any li child of the #parent element that is active (:focus).
You can use click, keydown, keyuyp events attached to document, $("#parent [tabindex]") selector, .is() , :focus
function checkFocus() {
console.log("descendant is active:"
, $("#parent [tabindex]").is(":focus")
, this.activeElement.tagName)
}
$(document).on("click keydown keyup", checkFocus)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent" tabindex="0">
<h1 tabindex="0"> my Header </h1>
<p tabindex="0">some text</p>
<ul tabindex="0">
<li tabindex="0">item 1</li>
<li tabindex="0">item 2</li>
<li tabindex="0">item 3</li>
</ul>
</div>

How to take an li and put it into specific DIV

I'm new to jquery and I'm doing a slider.
I have:
<ul>
<li> <img src="image.jpg"><p>description of the current image</p></li>
<li> <img src="image.jpg"><p>description of the current image</p></li>
<li> <img src="image.jpg"><p>description of the current image</p></li>
<li> <img src="image.jpg"><p>description of the current image</p></li>
</ul>
what I need to do is when I click on a specific <li> element, it will be displayed in a lightbox with its content.
<div id="lightbox">Here is clicked li and its content</div>
I don't know really where to start.
How do I tell jQuery to take a li and put into div?
You could do as follows:
$(document).ready(function() {
$('li').on('click', function() {
$('#lightbox').html($(this).html());
});
});

Trigger event with same ID elements

I have a menu list that refer to different projects.
Each list item shares its "ID" with a project showcased in a gallery.
<div class="menu">
<ul>
<li id="id1">project 1</li>
</ul>
</div>
<div class="gallery">
<div class="proc id="id1">project 1</div>
</div>
I'd like a jQuery function that :
When a list item from the menu is clicked, gets the project with the same id to do something.
I really don't know where to start from and I'm stuck at that :
<script>
$( "li#id1").click(function() {
$( ".project#id1" ).show();
});
</script>
Many thanks
As the comments said the IDs must be unique and you have missing quote.
You can use data attributes to handle your logic or combination of ids and data attributes.
Try something like this:
HTML
<div class="menu">
<ul>
<li data-project-id="first-project-id">project 1</li>
...
</ul>
</div>
<div class="gallery">
<div class="proc" data-project-id="first-project-id">project 1</div>
</div>
JavaScript
$('.menu li').click(function(){
var targetId = $(this).attr('data-project-id');
$('.proc[data-project-id="' + targetId + '"]').show();
});
The click event is attached to every li item in the element with class .menu.
On click event we extract the data-project-id attribute from the clicked element, find the project elemenet from gallery and show it.
JSFiddle Demo
you can use normal id also (as selector)
HTML
<div class="menu">
<ul>
<li id="first-project-id">project 1</li>
...
</ul>
</div>
<div class="gallery">
<div class="proc" id="first-project-id">project 1</div>
</div>
jQuery
$('.menu li').click(function(){
var targetId = $(this).attr('id');
$('.proc[id="' + targetId + '"]').toggle();
});

Categories

Resources