Looking for a solution on how to detect if a li has a child ul or ol i discovered jquerys has() which is pretty awesome apart from I need to detect if only the actual clicked li has a child ol, not any of its siblings. Are there any ways of doing this? The documentation doesnt cover this.
HTML
<ol>
<li><a class="delete-li" href="">Page 1</a></li>
<li><a class="delete-li" href="">Page 2</a></li>
<li><a class="delete-li" href="">Page 3 has ol</a>
<ol>
<li><a class="delete-li" href="">Page 4</a></li>
<li><a class="delete-li" href="">Page 5</a></li>
<li><a class="delete-li" href="">Page 6</a></li>
</ol>
</li>
</ol>
JS
$('.delete-li').live('click', function(event){
event.preventDefault();
item_id = $(this).attr('rel');
clicked = $(this);
////////////////////
//check if has sub pages
if(clicked.has('ol')){
answer = confirm('This will delete all sub pages and content are you sure?');
console.log(answer);
if(answer===true){gogogo=true;
}else{gogogo=false;}
}else{ gogogo=true;}
//if yes run AJAX delete
if(gogogo===true){
alert('LI REMOVED');
}
////////////////
});
Checkout the jsfiddle for the code.
has returns a jQuery object which is always true, as your handler is bound to a elements you can use next method and length property:
if ( clicked.next('ol').length )
Note that live method is deprecated, you can use on method instead.
$(document).on('click', '.delete-li', function (event) {
event.preventDefault();
var gogogo = false, $clicked = $(this), item_id = this.rel;
////////////////////
//check if has sub pages
if ($clicked.next('ol').length) {
gogogo = confirm('This will delete all sub pages and content are you sure?');
// console.log(gogogo);
}
if (gogogo === true) {
alert('LI REMOVED');
}
});
http://jsfiddle.net/jMF42/
You are binding the click handler to the a element. You need to be in reference to the li.
listItem = $(this).parent('li');
//check if has sub pages
if (listItem.find('ol').length) {
...
}
jsfiddle
You are calling function on <a> tag, which doesnt have child. If you want to get deeper you need to refer from his parent <li>.
$('.delete-li').on('click', function (event) {
event.preventDefault();
$this = $(this);
if ($this.parent('li').children('ol').length) {
answer = confirm('This will delete all sub pages and content are you sure?');
alert(answer);
} else {
alert('dont');
}
});
http://jsfiddle.net/NGmz6/
Related
I have a function where I have a list of links, where when the list link is clicked, it doesn't open a link until it's clicked again. Can someone please tell me how to get this working?
Here is the HTML:
<ul>
<li class = "submenu"> <a class="nav-link" href = "" > About </a> </li>
<li class = "submenu"> <a class="nav-link" href = "" > Gallery </a> </li>
<li class = "submenu"> <a class="nav-link" href = "" > Contact </a> </li>
</ul>
Here is the function:
(function() {
$('.nav-link').delegate("a", "click", function(e){
e.preventDefault();
});
})();
Here's a method using pure JS:
document.getElementsByClassName('nav-link').forEach(e => {
let wasClicked = false;
e.onclick = () => {
if (wasClicked) return true;
wasClicked = false;
// add a class to it
e.className += ' was-clicked-once';
return false; // reject the click
}
});
The delegate method is deprecated since jquery version: 3.0
Use the jquery on() method. it attaches an event handlers for the selected elements and child elements.
(function() {
$('.nav-link').on("click", function(e){
e.preventDefault();
});
})();
I am trying to find out which exact list item was selected in the navigation menu. With this information, I will remove the class active from the previous menu link and add it to the newly selected one.
<ul class="nav navbar-nav navbar-right">
<li class="active">Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
JavaScript:
let menuClick = document.getElementsByClassName(".nav");
menuClick.addEventListener('click', changeActive(), false);
function changeActive(){
//enter code here
}
Using
Vanilla JS - DEMO
var menuItems = document.querySelectorAll(".nav a"); // Get all matching selectors; same as SizzleJS $(selector)
for(var i=0; i < menuItems.length; i++){ // Loop through each element and add click event listener
menuItems[i].addEventListener('click', function(event){ // adding event listener.
event.preventDefault();
for(var i=0; i < menuItems.length; i++){
menuItems[i].parentElement.className = ''; // remove current `active` class from parent element `li`. This is not the best approach for removing classes in Vanilla JavaScript; see this answer http://stackoverflow.com/a/2155786/2151050
}
this.parentElement.className = 'active'; // add `active` to current clicked element.
}, false);
}
I am not going to force you to use jQuery, but you should consider it for doing more, and writing less code. :). Here's the jQuery version
jQuery - DEMO
var menuItems = $(".nav a");
$(".nav a").on('click', function(event) {
event.preventDefault();
menuItems.parent().removeClass('active');
$(this).parent().addClass('active');
});
Get the first element of the nodelist for nav:
let menuClick = document.getElementsByClassName("nav")[0];
Attach an event listener (note: changeActive not changeActive()). This will use event delegation to catch the events that bubble up from the anchors.
menuClick.addEventListener('click', changeActive, false);
Now add some code to your function:
function changeActive(e){
// grab the element that's active
let active = this.querySelector('li.active');
// remove the class
active.classList.remove('active');
// add the active class to the parent of the clicked anchor
e.target.parentNode.classList.add('active');
}
DEMO
There is many way to do that:
You can use onhashchange to detect hash changes
function locationHashChanged() {
if(location.hash === "#pageOne") {
// do something
}
else if(location.hash === "#pageTwo") {
// do something
}
}
window.onhashchange = locationHashChanged;
Or simply can bind click event to menu items
HTML:
<ul class="nav navbar-nav navbar-right">
<li class="active">Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
JS:
var navs = document.querySelectorAll('.nav a');
navs.click = function (e) {
document.querySelector('active').className.replace('active','');
var target = e.target;
taret.className += ' active';
};
here is way a way with javascript..Note you will have to loop to add a click handler to all objects in the menu.
here is a snippet
function click(e){
alert(e.target.innerHTML);
}
var el=document.getElementsByClassName('nav navbar-nav navbar-right')
for(var i=0;i<el.length;++i){
function t(i){
el[i].addEventListener('click',click,false)
}
t(i)
}
<ul class="nav navbar-nav navbar-right">
<li class="active">Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
I used different anchor tags on my list but it is not working due to the JavaScript file attach to that list. when I remove that JavaScript file it works but I have to included my JavaScript too. Is there a way to used that same JavaScript file with anchor tag working?
function prepareList() {
$('#expList').find('li:has(ul)')
.click(function (event) {
if (this == event.target) {
$(this).toggleClass('expanded');
$(this).children('ul').toggle('medium');
}
return false;
})
.addClass('collapsed')
.children('ul').hide();
$('#expandList')
.unbind('click')
.click(function () {
$('.collapsed').addClass('expanded');
$('.collapsed').children().show('medium');
})
$('#collapseList')
.unbind('click')
.click(function () {
$('.collapsed').removeClass('expanded');
$('.collapsed').children().hide('medium');
})
};
$(document).ready(function () {
prepareList()
});
I also attach jquery-1.4.2.min.js file as well
here is my html code:
<div id="listContainer">
<ul id="expList">
<li>
<p class="exp1">INDUSTRIAL</p>
<ul>
<li>
<p class="exp1">APPARELS</p>
<ul class="italic">
<li>
<a>Coveralls</a>
</li>
<li >
Uniforms
</li>
<li >
Aprons
</li>
<li >
Trousers
</li>
<li >
Kevlar Lined Denim Jeans
</li>
</ul>
</li>
<li>
<p class="exp1">GLOVES</p>
<ul class="italic">
<li >Seamless</li>
<li>Cut & Sewn</li>
<li>Leather</li>
<li>Mechanics</li>
</ul>
</li>
<li>
SLEEVES
</li>
</ul>
</li>
</ul>
</div>
I cannot tell you the reason for the anchor tags not working without seeing the javascript file you have linked to your page.
If you place this after you include your javascript file, your links should be working as normal.
If you have any anchors being created after the page has loaded (dynamic data) you can simply call Links(); to apply the onclick event handlers or you can manually add addEventListener('click',Anchors,false) when creating the anchor tag.
function Links(){
//Get all Anchor elements
var a=document.getElementsByTagName('a');
//Loop through each anchor element found.
for(var i=0; i<a.length; i++){
//Set on click event for the anchor element
a[i].addEventListener('click',Anchors,false);
}
}
function Anchors(){
//Set new window location using the anchor href that triggers this function.
window.location.href=this.href;
}
window.onload=Links;
If you have any questions about the source code above please leave your comment(s) below.
I hope this helps. Happy coding!
You have screwed up tag id in :
$('#expList') // <-- it was #expandList
.unbind('click')
.click(function () {
$('.collapsed').addClass('expanded');
$('.collapsed').children().show('medium');
})
Check out here: https://jsfiddle.net/urahara/u809p5yr/
But it's still foggy to me what you are trying to accomplish, and how. Cheers ;)
I had similar issues with my web page. I post the workaround here in case anyone else is struggling with it.
In my case I've accidentally removed the class name from my javascript code and the function was triggering with every <a> tag in my page!!
The old one:
$("a").on("click", function (e) {
// ... my function ...
});
and the right way:
$(".the-classname").on("click", function (e) {
// ... my function ...
});
In your case I think the return false is preventing the tag from working. Go ahead and delete it and check if it works fine.
I have write code to make the li active on url basis .It works fine but it fails on child li.It make child li active while i want that top li should be active not child.My code is below:
<script type="text/javascript">
jQuery(function () {
setNavigation();
});
function setNavigation() {
// this portion code make li active on url basis
var pathname = window.location.pathname;
path = pathname.replace(/\/$/, "");
path = decodeURIComponent(path);
var value = jQuery(location).attr('href');
// value = value.replace('.html', ''); alert(value);
jQuery(".flexy-menu a").each(function () {
var href = jQuery(this).attr('href');
if (value === href) {
jQuery(this).closest('li').addClass('active');
}
});
// this is code for child li but only first code works
jQuery('.flexy-menu').children('li').click(function(){
jQuery(this).parent('li').addClass('active');
});
}</script>
My HTML is like this :
<ul class="flexy-menu orange">
<li style="">Home</li>
<li style="">Collection
<ul style=""> <li>My Secret Garden </li>
<li>Legend</li></ul>
</li>
<li class="active" style="">Artisans</li>
<li style="">Contact </li>
</ul>
Instead of parent use .closest():
jQuery(this).closest('li').addClass('active');
and put this in doc ready:
jQuery(function () {
setNavigation();
jQuery('.flexy-menu').find('li').click(function(){
jQuery(this).closest('li').addClass('active');
});
});
Here i changed your selector little bit with .find() instead of .children(), because .find() looks for grand child also and if you want to traverse up to the parent then use .closest() method.
I have write code to make the li active on url basis
Okay! then you can choose to do this:
$('a[href*="'+ path +'"]').parents('li').addClass('active');
This should work:
All to all you just need to do this only, no extra function required:
jQuery(function () {
var path = window.location.pathname;
$('a[href*="'+ path +'"]').parents('li').addClass('active');
jQuery('.flexy-menu').find('li').click(function(){
jQuery(this).closest('li').addClass('active');
});
});
jQuery('.flexy-menu > li').click(function(e){
jQuery(this).closest('li').addClass('active').siblings().removeClass('active');
e.preventDefault();
});
Demo:
http://jsfiddle.net/hqPQu/
I am working on a web site. The type of menu that I want to create is one where you click on something in the menu, and a submenu pops up. But then you can also hover over any other menu item and another submenu will come up, hiding the first one you clicked. You can click anywhere to close the submenu.
I hope that was clear enough, and would appreciate any help you can give.
Here's my very, very simple, cheap, brief, ugly, lazy, father-disappointing version. It uses jQuery, and it probably doesn't actually look anything like what you wanted. But it accomplishes (I think) the one important thing: "locking" the sub-menu open until either another one is opened, or the user clicks somewhere else on the page.
The HTML looks like this...
<ul>
<li>
<a class="author" href="#">Menu Item 1</a>
<ul class="books">
<li><a class="book" href="#">Sub-Menu Item 1</a></li>
<li><a class="book" href="#">Sub-Menu Item 2</a></li>
</ul>
</li>
<!-- ... -->
</ul>
...and here's the JavaScript:
(function ($) {
var $current,
closeSubMenu = function () {
if ($current) {
$current.slideUp();
}
},
openSubMenu = function (e) {
var $books = $(this).next();
e.preventDefault();
e.stopPropagation();
if (!$current || $current[0] !== $books[0]) {
closeSubMenu();
$current = $books;
$books.slideDown();
}
};
$(document).click(function (e) {
var $target = $(e.target);
if ($target.hasClass('author')) {
openSubMenu.call(e.target, e);
} else if ($target.hasClass('book')) {
e.preventDefault();
} else {
closeSubMenu();
$current = null;
}
});
$('.books').slideUp();
}(jQuery));
If nothing else, it should help give you some ideas for how you do decide to do it.