Trying to build a dropdown menu. The idea is to add class to parent and child on parent hover, and remove added class when mouse is out of both.
This is html
<ul>
<li class="menuitem"></li>
<li class="menuitem">
<ul></ul>
</li>
<li class="menuitem"></li>
</ul>
And this is jquery
$(".menuitem").each(function(){
$(this).hover(function(){
$(this).addClass("visible");
$(this).find("ul").addClass("visible");
});
});
$(".visible").each(function(){
$(this).mouseout(function(){
$(this).removeClass("visible");
});
});
The event handlers are bound to elements that match at the time of binding. Adding a class later doesn't make the event handler work for that class.
What you seem to be looking for, is just toggleClass
$(".menuitem").hover(function(){
$(this).find('ul').addBack().toggleClass("visible");
});
FIDDLE
hover() actually incorporates 2 events ... mouseenter and mouseleave. If you only provide one callback argument it gets used for both events.
If you provide 2 callbacks the first is for enter and the second is for leaving so you can do:
function enterEl(){
$(this).addClass('visible').find('ul').addClass('visible');
}
function leaveEl(){
$(this).removeClass('visible').find('ul').removeClass('visible')
}
$(".menuitem").hover(enterEl, leaveEl);
This is more verbose than using toggle methods but is to point out that you can do different things in the two event handlers.
This is also the same thing as doing
$(".menuitem")
.mouseenter(enterEl)
.mouseleave(leaveEl);
Related
In my website, I have a dynamically growing list, (from a database) that has buttons attached to each item of the list. The button goes to the same javascript function, but each element in the list has a different id, which needs to be included inside the function when it is running.
I'm currently using onclick in the html and can pass the id through the function's parameter, as I am using template literals to render the list.
Is there any way that I can do this with event listeners?
An example of what I currently have would be:
onclick="theFunction('id')"
which changes for every item in the list, so the list could look like
<ul>
<li onclick="theFunction('id1')">name1</li>
<li onclick="theFunction('id2')">name2</li>
<li onclick="theFunction('id3')">name3</li>
</ul>
Use event delegation instead: attach one listener to the <ul>, and then on click, check to see if the clicked element was a <li>. If so, check an attribute of the <li> to figure out what parameter to call theFunction with. For example:
const theFunction = console.log;
document.querySelector('ul').addEventListener('click', (e) => {
if (!e.target.matches('li')) {
return;
}
const param = 'id' + e.target.dataset.param;
theFunction(param);
});
<ul>
<li data-param="1">name1</li>
<li data-param="2">name2</li>
<li data-param="3">name3</li>
</ul>
Note how the onclick attributes have been replaced with data-param attributes.
I have a rollover menu that has a class applied to <li> elements on hover, which toggles the visibility of a div inside it.
The class is called "cbp-hropen" and is applied when the <li> is hovered.
I'd like to trigger the visibility of another completely separate element called "menuDimmer" when this class is applied to the <li>.
<div class="menuDimmer"></div>
<div id="menu" class="main">
<ul>
<li>
MENU
<div class="cbp-hrsub">content...</div>
</li>
<li>
MENU 2
<div class="cbp-hrsub">content...</div>
</li>
</ul>
So I'd like something similar to:
if ($("li").hasClass('cbp-hropen')) {
$(".menuDimmer").fadeIn(100);
} else {
$('.menuDimmer').fadeOut(100);
}
(sorry, I know that code is poor but just trying to get the message across)
This has to work dynamically, rather than on page load, as the trigger element itself is only active on hover.
You can use an event to add the class :
$('#id').on('mouseover',function(){
//addclass
}
then you remove the class of your div
$('#id').on('mouseout',function(){
//removeclass
}
You can use the MutationObserverAPI
to listen for DOM changes on specified elements. Take a look at the provided code in this question, as it shows how to use MutationObserver to detect class changes. The MDN doc linked above provides a more general example too.
it removes the class but it doesn't add the class, i can't use .click() function it needs to be onclick=""
<li class="selected">Click me</li>
<li>Click me</li>
function myfunction(a,b,c){
$('ul li.selected').removeClass('selected').addClass('none');
$(this).closest('li').addClass('selected');
}
You are already using jQuery, so just use jQuery to handle all your events.
Add this code;
$(function(){
// bind click event to your <a> tags
$('a').click(function(e){
// prevent the default behaviour of your links
e.preventDefault();
// remove the class from all li's
$('li').removeClass('selected');
// add selected to the clicked a's parent li
$(this).parent('li').addClass('selected');
});
});
Then keep your html clean from JavaScript
<li class="selected">
Click me
</li>
<li>
Click me
</li>
p.s.
If you are wanting to put PHP in, then you could put things in like;
// check out my 1337 php coding skillz!
Click Me
Then access it in your jQuery using
$(this).data('foobar');
pps
Sorry my php coding skills are rubbish!
I have a list of links, one has the class active.
On my next button click id like to remove the class from the current element and add it to the next only I cant seem to get it to add?
Ive made a fiddle to hopefully explain my problem, any help would be great, thanks
http://jsfiddle.net/h6D4k/
$('.next').click(function(){
$('ul.pagination').find('a.active').removeClass('active');
$('ul.pagination').find('a.active').next('a').addClass('active');
return false;
});
One of the jQuery most usable conveniencies is that its methods are (usually) chainable - in other words, they return the very object they are called from. So you can simply write this:
$('ul.pagination').find('a.active').removeClass('active').closest('li')
.next('li').find('a').addClass('active');
... as it's <li> elements that should be 'nexted', not <a> ones. But in fact, you shouldn't probably discard 'active' altogether if it's the last element in question:
var $a = $('ul.pagination').find('a.active'),
$li = $a.closest('li'),
$nextLi = $li.next('li');
if ($nextLi.length) {
$a.removeClass('active');
$nextLi.find('a').addClass('active');
}
This is actually what you want based on your html structure in you fiddle. http://jsfiddle.net/h6D4k/1/
$('ul.pagination').find('a.active').removeClass('active').parent()
.next().find('a').addClass('active');
Because once you've done this...
$('ul.pagination').find('a.active').removeClass('active');
There is no more a.active - the active classname has been removed from that element. So repeating the same selector...
$('ul.pagination').find('a.active')//...
... will select nothing.
Chain it all together instead.
$('ul.pagination').find('a.active').removeClass('active').next('a').addClass('active');
You have a second problem. According to the jQuery API for next(), it will:
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.
You're not trying to get the following sibling:
<ul class="pagination">
<li><a class="one active" href="#">X</a></li>
<li><a class="two" href="#">X</a></li>
<li><a class="three" href="#">X</a></li>
</ul>
Next
Prev
You're trying to get the next <a> in the whole document. That's more challenging - and I'm not sure how to do it.
I would write it this way, preventing the action from doing anything on the last li as well.
http://jsfiddle.net/h6D4k/6/
$('.next').click(function(e){
e.preventDefault();
if ($("ul.pagination a.active").parent().is(":last-child")) return;
$('ul.pagination a.active').removeClass('active').parent().next().find("a").addClass('active');
});
You have two errors in your code:
Once removed, the active class can't be found anymore
your a tags are nested in li tags so next() doesn't work as you expect
To simplify things, you could attach the active class to the li tags.
Live demo: http://jsfiddle.net/h6D4k/7/
Code:
$('.next').click(function(){
$('ul.pagination').find('li.active').removeClass('active')
.next().addClass('active');
return false;
});
I have following html code. In my page there are many tag which have class='posta' but what i want assign onclick event only to which have post attribute.
<ul class="posts_li">
<li>
Post
</li>
<li>
Act
</li>
<li>
Event
</li>
<li>
Create News
</li>
</ul>
My Jquery Code for assigning an event is here
$(".posta").click(function(){
alert("here");
if($(this).attr("post")){
alert($(this).attr("post"));
}
});
$(".posta[post]").click(....);
Fiddle: http://jsfiddle.net/maniator/LmrPR/
Then use [attribute=value] in the selector:
Example
$('.posts_li').on('click', '.posta[post]', function() {
alert($(this).attr("post"));
return false;
});
Additionally, you can avoid placing an event handler for each item by delegating them to the parent. In this example, I placed a single handler on the <ul> for all child elements using the .on() method (jQuery 1.7+). For older jQuery (1.4.2+), .delegate() is also available.
Use can use attribute selectors [propertyname] to select only nodes that have that property.
$(".posta[post]").click(function(){ ... });
You can do this with the css/jquery attribute selector:
$(".posta[post]").click(......... your code here)
Here's the example:
http://jsfiddle.net/wHvkF/
I would accomplish it using:
See this working Fiddle example. the last from the list doesn't alert
$(".posta[post]").click(function(e) {
e.preventDefault();
alert("here");
});
Works since version 1.0 of jQuery.