I have footer with some content inside. ANd i made my footer show\hide on click. But now if i click on any item inside footer(i have navbar there) my footer reacting on show\hide aswell. How do i make only parent(footer) to react on clicks, and none of child elements? I'm using jquery mobile.
Here is my code:
<div data-role="footer" data-id="main_footer" data-position="fixed" data-fullscreen="true" data-visible-on-page-show="false" data-tap-toggle="false" >
<div data-role="navbar" data-iconpos="top">
<ul>
<li><a id="menu-item-home" data-icon="custom" href="index.html" class="ui-btn-active ui-state-persist"> </a></li>
<li><a id="menu-item-near-me" data-icon="custom" href="near-me.html"> </a></li>
<li><a id="menu-item-rewards" data-icon="custom" href="rewards.html"> </a></li>
<li><a id="menu-item-invite" data-icon="custom" href="invite.html"> </a></li>
<li><a id="menu-item-profile" data-icon="custom" href="profile.html"> </a></li>
</ul>
</div><!-- /navbar -->
</div>
<!-- /footer -->
</div>
And JS
$("#index").live('pagecreate', function() {
$("[data-role='footer']").live("click", function() {
if ($("[data-role='footer']").hasClass('ui-fixed-hidden'))
{
$("[data-role='footer']").removeClass('ui-fixed-hidden');
}
else
{
$("[data-role='footer']").addClass('ui-fixed-hidden');
}
});
});
TLDR;
I want to make links inside my footer to work, but not trigger footer to show\hide while click on link
You could add
$(document).on("click", "[data-role='footer'] li", function(e) {
e.stopPropagation();
});
Note that I used on instead of live, which is deprecated. Note also that jQuery has a useful toggleClass function. So I'd suggest you replace your existing code with
$("#index").live('pagecreate', function() {
$(document).on("click", "[data-role='footer'] li", function(e) {
e.stopPropagation();
});
$(document).on("click", "[data-role='footer']", function() {
$("[data-role='footer']").toggleClass('ui-fixed-hidden');
});
});
For a variety of reasons, you shouldn't actually use .live, but replace it with .on. Anyway, I think this will work:
... 'click', function (e) {
if ($(e.target).not("[data-role=footer]")) {
e.stopPropagation();
}
});
this should work...i suggest u to use on instead on live...
$(document).on("click", "[data-role='footer']", function(e) {
if(e.target != this){
return;
}
if ($("[data-role='footer']").hasClass('ui-fixed-hidden'))
{
$("[data-role='footer']").removeClass('ui-fixed-hidden');
}
else
{
$("[data-role='footer']").addClass('ui-fixed-hidden');
}
});
So your problem is that , the link in the footer not works. The easiest solution for this, is bind a click event to the link inside your footer and use either $.mobile.changePage() or window.location() method to open the desired url. Add this to your code :
$("[data-role=footer] a").bind("click",function(){
$.mobile.changePage($(this).attr("href"));
});
Related
I have a dropdown menu that has parent categories that display their children links automatically on Desktop and hide them on mobile until they are clicked. If the window is sized back up the children show again.
This almost works but after resizing the window, if I click the parent category on Desktop it will slideToggle the children elements. It will also run multiple slideToggle events after resizing rather than just one.
I am aware it is likely due to having two instances of slideToggle() but I was having issues when removing one or the other instances. Sometimes they would never open on mobile so I found putting both instances solved this.
I am looking for a less bloated and fully functioning solution. I appreciate all help and I hope to gain knowledge from the answers.
CodePen
//Start Ignore
$('li.dropdown a').on('click', function (event) {
$(this).parent().toggleClass('open');
});
$('body').on('click', function (e) {
if (!$('li.dropdown').is(e.target)
&& $('li.dropdown').has(e.target).length === 0
&& $('.open').has(e.target).length === 0
) {
$('li.dropdown').removeClass('open');
}
});
//End Ignore
/**** CODE I NEED HELP WITH BELOW ****/
$(window).resize(function(){
if ($(window).width()<768){
$('.top-nav-link').on('click', function(event){
event.preventDefault();
$(this).parent().parent().find('.dropdown-nested-links').slideToggle();
console.log('I worked.');
});
}else{
$('.dropdown-nested-links').css('display', 'inline-block');
}
});
if ($(window).width()<768){
$('.top-nav-link').on('click', function(event){
event.preventDefault();
$(this).parent().parent().find('.dropdown-nested-links').slideToggle();
});
}else{
$('.dropdown-nested-links').css('display', 'inline-block');
}
$(window).resize(function(){
if ($(window).width()>768){
//Expands the links when resized back to Desktop
$('.dropdown-nested-links').css('display', 'inline-block');
}else{
//Hides the category dropdown when resized back down to mobile
$('.dropdown-nested-links').css('display','none')
}
});
.dropdown-nested-links{
padding:0;
display:none;
}
#media only screen and (min-width:768px){
.dropdown-nested-links{
padding:0;
display:inline-block;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="navbar navbar-inverse">
<ul class="nav navbar-nav learn-nav">
<li class="dropdown">Click Me <span class="glyphicon glyphicon-menu-down"></span>
<ul class="dropdown-menu">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6 dropdown-section">
<li>Parent 1</li>
<ul class="dropdown-nested-links">
<li><span></span>Child</li>
<li><span></span>Child</li>
<li><span></span>Child</li>
</ul>
</div>
<div class="col-sm-6 dropdown-section inverse-section">
<li><a class="top-nav-link" href="#">Parent 2</a></li>
<ul class="dropdown-nested-links">
<li><span></span>Child</li>
<li><span></span>Child</li>
</ul>
</div>
</ul>
</li>
</ul>
</nav>
You should either remove the click event or make the condition inside the click event :
$('.top-nav-link').on('click', function(event){
if ($(window).width()<768){
event.preventDefault();
$(this).parent().parent().find('.dropdown-nested-links').slideToggle();
console.log('I worked.');
}
});
$(window).resize(function(){
if ($(window).width()>=768){
$('.dropdown-nested-links').css('display', 'inline-block');
}
});
I have searched a lot for adding active class to the parent menu using javascript.
I found many more examples but not a single one is working for me, below is my code
HTML
<div id="menu1" class="hmenu">
<ul>
<li>Item1
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
<li>SubItem2 </li>
<li>SubItem3
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
<li>Item2</li>
<li>Item3
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
My requirement is when i click on SubItem1 then both Item1 and SubItem1 should be active.
And when i click on SubSubItem1 then SubSubItem1 ,SubItem1 and Item1 should be active.
Means when click on any link then its all parent link and the same link should be active.
I have tried with this javascript code :
$(document).ready(function () {
$('.hmenu ul li ul').find('li').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents('li').addClass('active');
});
});
Actually i don't have any experience with javascript coding and unable to figure out the problem in my code.
Can anyone suggest me for the same.
The issue comes from .find('li').click().
As you use nestsed <li>, this will cause the event to be fired two times when you click on a child <li>. This causes problems. Can not you add the click() to <a> elements?
$(document).ready(function () {
$('.hmenu a').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents("li").addClass('active');
});
});
It works just fine: https://jsfiddle.net/6put8tdx/
Note that your page will be bumped to the top while clicking to a tab because of # anchor. If you want to prevent this, you may pass the event to the function .click(function (event) {...} and add event.preventDefault inside.
If you need the click target to be the LI element (as opposed to Delgan's answer)
you can use .not() over the targeted LI's parents to prevent messing with the bubbling event targets:
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault(); // Prevent page jumps due to anchors
var $par = $(event.target).parents("li"); // get list of parents
$(".hmenu .active").not( $par ).removeClass("active"); // not them
$(this).addClass('active'); // let the event propagation do the work
});
});
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault();
var $par = $(event.target).parents("li");
$(".hmenu .active").not($par).removeClass("active");
$(this).addClass('active');
});
});
.active > a{
background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu1" class="hmenu">
<ul>
<li>Item1
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
<li>SubItem2 </li>
<li>SubItem3
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
<li>Item2</li>
<li>Item3
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
To better understand the above
The following example works out-of-the-box, and the clicked one and all it's LI parents get the "active" class.
Why? Cause the event target is li, means any li of .hmenu - so that click is attached to any of them, and clicking the subsub LI the event will propagate to the LI parents - triggering the same click behavior (this add class)!
$(".hmenu").on("click", "li", function(){
$(this).addClass("active"); // Wow! Event propagation rulez!!
});
But we need to remove existing .active and here it gets messy...
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active"); // triggered on every event bubble :(
$(this).addClass("active"); // leaving only the main parent with active class
});
That's caused by the concurrency that happens while the event bubbles and triggers the same actions for the parent elements.
One way to prevent that concurrency would be using a setTimeout of 1ms:
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active");
setTimeout(function(){ // Let the previous finish the bubbling mess
$(this).addClass("active"); // Yey! all fine! Every LI has the active class
}, 1);
});
But here the timeout of 1ms can lead to visual "blinking" issues.
Try this:
$(function () {
$("li a")
.on("click", function () {
$(this).toggleClass("active");
$(this).closest("ul").parent().children("li a").toggleClass("active")
.parent().parent().parent().children("li a").toggleClass("active");
});
});
fiddle
Traverse from the clicked element. And use toggleClass() to avoid the mundane checking if hasclass removeClass ...
Pretty simple problem but it's been bugging me for almost an hour now. Basically, I want to update list classes onClick, then remove the class again when another item is clicked.
<nav>
<div class="menu-main-menu-container">
<ul id="menu-main-menu" class="menu">
<li class="current-menu-item">
<a class="scroll" href="#top"><span>Home</span></a>
</li>
<li class="">
<a class="scroll" href="#featured_work_anchor"><span>Featured Work</span></a>
</li>
<li class="">
<a class="scroll" href="#about_contact_anchor"><span>About/Contact</span></a>
</li>
</ul>
</div>
</nav>
jQuery
$(document).ready(function() {
$('#menu-main-menu li').on('click', changeClass);
});
function changeClass() {
$('#menu-main-menu li').removeClass('current-menu-item');
$(this).addClass('current-menu-item');
}
JSFiddle, ready to go. I appreciate any help. Perhaps I'm approaching the problem wrong or maybe missing something silly ?
The only problem I could see is the removeClass() function, either don't pass any argument so that all the classes in the li are removed or pass the class names to be removed.
function changeClass() {
$('#menu-main-menu li').removeClass('current-menu-item');
$(this).addClass('current-menu-item');
}
Demo: Fiddle(Also in the fiddle you forgot to include jQuery)
You need to pass the element that is being set as current:
$(document).ready(function() {
$('#menu-main-menu li').on('click', function(){
changeClass($(this));
});
});
function changeClass(element) {
$('#menu-main-menu li').removeClass('current-menu-item');
element.addClass('current-menu-item');
}
updated fiddle: http://jsfiddle.net/mw5sgcLn/4/
I have a JavaScript menu that I want to unfold/fold when I click on the #dropdown button. First, it took three clicks for it to unfold and after those three clicks, it worked perfectly fine.
I edited my code, I have to click it three times again for it to work, but after that, each click makes the menu fold/unfold three times in a row.
buttonClickHandler
function buttonClickHandler(e) {
e.preventDefault();
$(document).ready(function(){
$('#main').hide();
$('a#dropdown-button').click(function(){
$('#main').toggle(function(){
$('#main').addClass('active').fadeIn();
}, function(){
$('#main').removeClass('active').fadeOut();
return false;
});
});
});
}
Init
function init(){
var button = document.getElementById('dropdown-button');
button.addEventListener("click", buttonClickHandler, false);
}
window.addEventListener("load", init, false);
HTML
<section id="nav-bar">
<figure>
<span class="helper"></span><img src="img/Logo.png" alt="Zien Woningmarketing"/>
</figure>
<img src="img/Menu.png" alt="Menuknop: open het menu"/>
</section>
<nav id="main">
<ul id="firstLevel">
<li>Home</li>
<li>Producten</li>
<li>Woningmarketing</li>
<li>Over Zien!</li>
<li>Werkwijze</li>
</ul>
<ul>
<li class="login">Inloggen</li>
<li>Registreren</li>
</ul>
</nav>
Link to JSFiddle
The thing is that this menu should easily drop down, thus showing its contents.
Hope this help :
http://jsfiddle.net/x7xu4/2/
$(function(){
$("a#dropdown-button").on("click",function(event ){
$("#main").toggleClass('active').fadeToggle();
event.preventDefault();
});});
Since you are using jquery 2.1, instead of "click" use "on" for it saves a bit of memory, and I edited your code for a simpler solution.
I make simpler your code
$(function(){
$('a#dropdown-button').click(function(){
if(!$('#main').hasClass('active')){
$('#main').addClass('active');
$('#main').show();
}else {
$('#main').removeClass('active');
$('#main').hide();
}
return false;
});
});
Here is jsFiddle sample
HTML:
<div class="container-fluid">
<div class="sidebar">
<ul class="pills">
<li id="l1"><a id="link1">Lesson 1</a></li> <hr>
<li id="l2"><a href="#" >Lesson 2</a></li> <hr>
<li id="l3"><a href="#" >Lesson 3</a></li> <hr>
</ul>
<div class="span16" id="target">
</div>
Javascript:
$('#l1').click(function(){
$('#target').fadeOut('fast', function(){
$('#target').load("lesson/lesson1.html", function(){
$('#target').fadeIn('slow');
});
});
});
I have 5 links within my webpage, I was wondering if there was anyway to make this one piece of code instead of copy + pasting it multiple times.
$('a.AjaxLink').click(function(){
var url = this.href;
$('#target').fadeOut('fast')
.load(url, function(){ $(this).stop(true, false).fadeIn('slow'); });
});
return false;
});
This code handles the click event for all <a>s with a class of AjaxLink.
In the click handler, it grabs the href, fades out your #target, and performs the AJAX load.
When the AJAX load finishes, it stops the animation (in case the AJAX was faster than the fade), then fades it back in.
Finally, it tells the browser not to take the default action (navigating to the page) by returning false.
Use class instead of id. Select elements using class.
Also you can use .each() method
You could do this with a new jQuery method. Given this HTML:
<a class="hello" href="#">Hello</a>
<a class="goodbye" href="#">Goodbye</a>
<div id="target"></div>
You'd use this code:
jQuery.fn.switchTarget = function( target, href ) {
var $target = $(target);
this.bind( 'click', function(e) {
e.preventDefault();
$target.fadeOut('fast', function() {
$target.load( href, function() {
$target.fadeIn('slow');
});
});
});
return this;
};
$('.hello').switchTarget( '#target', 'hello.html' );
$('.goodbye').switchTarget( '#target', 'goodbye.html' );