Select multiple li's and it's first child using jquery - javascript

Am trying to add a onclick event to the a tag of particular li's which are under a ul with id #nav.
HTML Structure:
<ul id="nav">
<li>link1</li>
<li>
link2
<ul>
<li>innerlink1</li>
<li>innerlink2</li>
</ul>
</li>
<li>link3</li>
<li>
link4
<ul>
<li>innerlink1</li>
<li>innerlink2</li>
</ul>
</li>
</ul>
Jquery
$( document ).ready(function() {
$("ul#nav li").eq(1).children().first().click(function(){
$(this).attr('onclick', 'return false;');
return false;
});
$("ul#nav li").eq(5).children().first().click(function(){
$(this).attr('onclick', 'return false;');
return false;
});
});
If you see, am writing jQuery twice to select the a element of li item which has got another ul inside and add onclick event to it. This is working fine. But is there way to reduce my code and make it more clean?

So you don't want the li that contains an ul child to fire the click event so i think it would be like this
$('#nav li:has(>ul)').click(function (event) {
event.preventDefault();
alert('click');
});
fiddle can be found here: http://jsfiddle.net/552T4/3/

Hey you may be looking for this:
$("ul#nav li:has(>ul)")

$("ul#nav li:eq(1),ul#nav li:eq(5)").children().click(function(){
e.preventDefault();
var youClicked=$(this).text();
alert(youClicked);
});

Please try this.
$( document ).ready(function() {
$("#nav > li").each(function(){
$(this).find('a').attr('onclick', 'return false;');
});
});
Below is fiddle of this.
Js Fiddle
In above i apply "onclick" event to all anchor. if you want to apply only that li which has child ul then the code is something like this.
$( document ).ready(function() {
$("#nav > li").each(function(){
if($(this).find('ul').length>0)
{
$(this).find('a').attr('onclick', 'return false;');
}
});
});
below is the link for Li with Ul element selected.
li with ul onclick

Yea, Add ID's to the elements you need:
HTML Structure:
<ul id="nav">
<li>link1</li>
<li>
link2
<ul>
<li>innerlink1</li>
<li>innerlink2</li>
</ul>
</li>
<li>link3</li>
<li>
link4
<ul>
<li>innerlink1</li>
<li>innerlink2</li>
</ul>
</li>
</ul>
Jquery
$("#liOne, #liTwo").click(function(e){
e.preventDefault();
return false;
});
Or even a class, instead of id's.
This way, you only have to add the id / class attributes to the elements you want the click event to be handled on, instead of traversing the DOM like that.

Related

change active class of ul list using anchor tag click

I am trying to add or remove active class for list element by clicking the link inside it.
<ul>
<li id="l1" class=""> one</li>
<li id="l2" class="">two</li>
</ul>
$('.btn1').click(function() {
$( "#l1" ).addClass( "active" );
$( "#l2" ).removeClass( "active" );
window.open ('/one');
});
$('.btn2').click(function() {
$( "#l2" ).addClass( "active" );
$( "#l1" ).removeClass( "active" );
window.open ('/two');
});
My html and css classes as above. But it doesn't work as expected. So anyone know how to resolve it?
$('.btn').click(function() {
$('.btn').closest('li').removeClass("active")
$(this).closest('li').addClass("active")
console.log($(this).data("url"))
})
li.active{color:red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li id="l1" class=""> one</li>
<li id="l2" class="">two</li>
</ul>
My HTML and CSS classes as above
Basically, your code works well. You need to add CSS like .active{ color:red;}.
However, listen to the event click for each button is not a good thing to do. Imagine you have about 10/100/1000 button then you have to Copy/Pase code like this?
You should keep in mind that: Don't repeat yourself.
So as a result, I've refactored code for you like below. Cheers!
$('.btn').click(function() {
$('.btn').closest('li').removeClass("active");
$(this).closest('li').addClass("active");
var content = $(this).data('value');
$("#content").html(content);
});
.active{
color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li id="l1" class=""> one</li>
<li id="l2" class="">two</li>
</ul>
<div id="content" style="width:100px; height: 100px">
</div>
Edit
Basically, you should get content then assign it to div content below instead of navigating. If you still want to navigate, you should store your data by using localStorage
Try:
$(".btn1").click(function(){
$("ul li").removeClass('active');
$("#l1").toggleClass('active');
window.open ('/one');
});
Note line 2
// will remove class active from all bullets in all list add a #id to the selector to specify a specific list.
// One click handler for all buttons/links.
$('.btn').click(function(event) {
// Remove class from all buttons.
$('.btn').parent().removeClass('active');
// Get the specific button that was clicked.
var btn = $(this);
// Add active class to it's parent.
btn.parent().addClass('active');
//open from the data-link attribute on the link.
// though, window.open will probably be blocked by the browser popup blocker.
window.open(btn.attr('data-link'));
});
.active {
background-color: #ff0000;
}
a.btn {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<!-- you could save where to link to in a data attribute, though I am not sure why you wouldn't just have it in href -->
<li id="l1" class=""> one</li>
<li id="l2" class="">two</li>
</ul>

jQuery - get id of a nested single <li> element when right click it

I found a lot of questions about this, but I have problem with getting the single id of a nested li element, and I couldn't find answer for it. Here is my code:
$(function() {
$('ul').on('contextmenu', 'li', function(e) {
e.preventDefault();
console.log(this.id);
});
And here is my HTML:
<ul id="u-main-ul">
<li id="1"> 1
<ul id="u-1">
<li id="11">11</li>
</ul>
</li>
</ul>
The problem is that when I right click on the li element with id="11", on the console it writes "1 11". When click one li element it shows and the id of all others li tags that are placed before the clicked one.
I want to get the id only of the right-clicked li tag and nothing else.
You need to stop the event from bubbling up the tree:
$('ul').on('contextmenu', 'li', function(e) {
e.preventDefault();
e.stopPropagation();
console.log(this.id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="u-main-ul">
<li id="1">1
<ul id="u-1">
<li id="11">11</li>
</ul>
</li>
</ul>
See the documentation for more info.
Try it with stopPropagation() like so
$(function() {
$('ul').on('contextmenu', 'li', function(e) {
e.stopPropagation();
console.log(this.id);
})
});
See the JSFiddle

Prevent default only on some levels

I am making a menu that has submenu. When I click on a menu item I am using prevent default because it is a tags, but on the submenu level I don't want to prevent default. I haven't been able to figure out how to make it work so it doesn't affect the top level.
<div id="block-menu-block-2">
<ul class="menu">
<li>
1
</li>
<li>
2
<ul class="menu">
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
<li>2.4</li>
</ul>
</li>
<li>
3
<ul class="menu">
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
<li>3.4</li>
</ul>
</li>
<li>
4
</li>
<li>
5
</li>
<li>
6
<ul class="menu">
<li>6.1</li>
</ul>
</li>
</ul>
</div>
Here is the jQuery
$('#block-menu-block-2 ul li').on("click", function() {
if ($(this).children().is('ul')) {
if ($(this).find('ul').is(':visible')) {
$(this).find('ul').hide("blind");
$(this).removeClass('menuItemSelected');
$(this).find('ul').removeClass('menuItemSelected');
} else {
$(this).parent().find('li ul').hide("blind");
$(this).parent().find('.menuItemSelected').removeClass('menuItemSelected');
$(this).find('ul').show("blind");
$(this).addClass('menuItemSelected');
$(this).find('ul').addClass('menuItemSelected');
};
event.preventDefault()
}
});
Here is a codepen for reference: http://codepen.io/mathiasha/pen/bVpMyo
Added some stuff. Changed some stuff. Couldn't paste into codepen from my phone so this might not work. Code first, then word wall.
$('#block-menu-block-2 ul li').each (function () {
var $this = $(this);
if ($this.find ('ul:first').length > 0) {
$this.click (function () {
if ($this.find ('ul:visible').length > 0) {
$this.removeClass ('menuItemSelected').find ('ul').removeClass('menuItemSelected').hide ('blind');
} else {
$this.parent ().find ('ul li').hide ('blind');
$this.parent ().find('.menuItemSelected').removeClass ('menuItemSelected');
$this.addClass ('menuItemSelected').find ('ul').show ('blind').addClass ('menuItemSelected');
}
});
}
});
$('#block-menu-block-2 > ul > li > a').click (function (e) {
if ($(this).find ('ul:first').length > 0)
e.preventDefault ();
});
The real answer lies in only putting the preventDefault only on the a tag and only when it is the immediate child of a li tag tjat is the immediate child of a ul tag that is the immediate child of the block-menu. See the last 3 lines.
The rest of the code below should only add the click listener to li tags with ul tags inside. Tried to use chaining to limit the number of jQuery objects created. Might have messed up what it was doing. You only really need to remove preventDefault from where it is and than use the last 3 lines.
Can you not add a class to your submenu triggers, e.g. .submenu-trigger, and then use the following jQuery:
$(document).on('click', function(e) {
if ($(e.target).hasClass('submenu-trigger')) e.preventDefault();
});
Ignoring all the other menu manipulation and putting the event on <a> tags you can simply check if the <a> has a sibling <ul> and if it does prevent default
$('#block-menu-block-2 a').click(function(e){
if( $(this).siblings('ul').length ){
e.preventDefault();
}
// menu manipulation code
});

How to get all parents of <li> tag onclick of it?

I am designing dynatree so nodes are place in ul and li tags. the problem I am getting is I am not getting parents of clicked li element.
Here is my html code,
<ul class="bulk">
<li>gp1
<ul>
<li>gp2
<ul>
<li>gp3
<ul>
<li>c1
<li>c2
<li>c3
</ul>
<li>gp4
</ul>
</ul>
<li>gp5
<ul>
<li>gp6
<ul>
<li>gp7
<ul>
<li>c4
<ul>
<li>c5
<li>c6
</ul>
</ul>
<li>gp8
<li>gp9
</ul>
<li>gp10
</ul>
</ul>
Here is my jquery method
$('ul.bulk li').click(function(e)
{
//alert($(this).find("span.t").text());
alert(e.html());
});
Here is my fiddel http://jsfiddle.net/raghavendram040/ojnLrcjz/
The problem I am getting is if click on gp3 it alerts me 3 times, but I want if I click on gp3 it should alert its parents(gp1 and gp2). Here I place all li and ul dynamically except tag. How to achive this please help me in this
You can do something like
$(function () {
$('ul.bulk li').click(function (e) {
if($(e.target).is(this)){
$(this).parentsUntil('.bulk', 'li').each(function(){
alert(this.firstChild.nodeValue)
})
}
});
});
Demo: Fiddle

prev or siblings select jQuery

<li class="page_item ">A
<ul class="children">
<li class="page_item">1</li>
<li class="page_item">2</li>
</ul>
</li>
<li class="page_item ">B
<ul class="children">
<li class="page_item">1</li>
<li class="page_item">2</li>
<li class="page_item">3</li>
<li class="page_item">4</li>
</ul>
</li>
$('.children a').click(function(event){
event.stopPropagation();
$('ul.children').prev().css('background','red');
});
ONLINE SAMPLE: http://jsfiddle.net/uybPf/
I'd like to achieve when I click A or B's submenu, and then A or B will be highlighted. but my code highlighted all of them. I don't want to use toggleClass() could someone please help to fix my code. Thanks
That's because you're using ul.children which will perform the code for every element in that set. Try this instead:
$('.children a').click(function(event){
event.stopPropagation();
$("ul.children").prev().css('background','none');
$(this).closest("ul.children").prev().css('background','red');
});
DEMO: http://jsfiddle.net/uybPf/6/
$('.children a').click(function(event) {
event.stopPropagation();
$(this).closest('ul.children').prev().css('background', 'red');
});
http://jsfiddle.net/uybPf/2/
You should use closest or parent methods:
$('.children a').click(function (event) {
event.stopPropagation();
$('.page_item a').removeClass('highlight'); // remove previously active class
$(this).closest('.children').prev().addClass('highlight');
});
http://jsfiddle.net/uybPf/3/
You should better use addClass and removeClass methods instead of css since you already defined .highlight class in CSS.
Try this
$('.children a').click(function(event){
event.stopPropagation();
$('>a:first', $(this).closest('.children').closest('.page_item')).css('background', '#f00')
});
This however doesn't unhighlight the previously highlighted parent
After reading your question's comments, edit:
add
$('.page_item > a').css('background','transparent');
after
event.stopPropagation();
Try this
$('.children a').click(function (event) {
event.stopPropagation();
$(this).closest('ul.children').parent().children('a').css('background', 'red');
});
http://jsfiddle.net/uybPf/2/

Categories

Resources