I have using the following code for developing tabs.
$(document).ready(function() {
$('#container-1').tabs();
}
....
<div id="container-1">
<ul>
<li><span>Home</span></li>
<li><span>Contact</span></li>
</ul>
</div>
...
It works fine! I need the tab click event. If it is the Home tab click, I have to do alert();. How do I achieve this?
Set the id of the Home tab span element:
<li><span id="home">Home</span></li>
And add the click handler to it somewhere:
$("#home").click(function()
{
alert("Home tab is selected!");
});
Personally, I'd handle it all in the tab configuration itself rather than adding click events to the elements which ultimately will be the clickable part of the tab. If you do it via the tab config, then all of your tab logic is centralized thus making things cleaner and you don't need to be familiar with the implementation details of the tabs:
$(document).ready(function() {
$('#container-1').tabs({
selected : function(e, ui) {
if (ui.index == 0) {
alert('Home clicked!');
}
}
});
});
....
<div id="container-1">
<ul>
<li><span>Home</span></li>
<li><span>Contact</span></li>
</ul>
</div>
If you want the tab click event, you would do something like one of the following.
$("#tabid").click(function(e) {
e.preventDefault();
// Do tab click logic
});
or
$(".tabclass").click(function(e) {
e.preventDefault();
// Do tab click logic
});
Do a search for jQuery cheat sheet to get yourself a very useful jQuery cheat sheet.
Related
I am building a hybrid application out of Jquery Mobile, Cordova and WordPress. My current question is regarding my navigation between "pages" in index.html that have the data-role="page" attribute.
Current Setup: I am using data-role="navbar" inside data-role="header" and EACH page has the following header:
<div data-role="navbar">
<ul>
<li><a class="blue-button home-button" href="#" data-transition="slidefade">HOME</a></li>
<li><a class="blue-button artist-refresh artist-button" href="#" data-transition="slidefade">ARTIST</a></li>
<li><a class="blue-button show-button" href="#" data-transition="slidefade">SHOW INFO</a></li>
</ul>
</div><!-- /navbar -->
main.js file I am trying to add event listeners to each of the navigation elements by class name and .ui-page-active class I am also bundling in a few other unique elements that have clickEvents but I reference them by ID:
function setupMainNav() {
console.log("Settign Up SUB NAV");
$('.ui-page-active .show-button').on('click', function () {
console.log("In the show info click");
$.mobile.changePage("#show-info", {
transition: "slide"
});
});
$('.ui-page-active .home-button').on('click', function () {
console.log("In the show info click");
$.mobile.changePage("#home", {
transition: "slide"
});
});
$('#artistContactButton').on('click', function () {
console.log("Show Contact Form");
$.mobile.changePage("#artist-contactpage", {
transition: "slide"
});
});
$('div.ui-page-active a.artist-button').on('click', function () {
console.log("artist button click");
$.mobile.changePage("#cyan-home", {
transition: "slide"
});
});
$('#show_link').on('click', function () {
$.mobile.changePage("#cyan-home", {
transition: "slide"
});
});
$('#shop_link').on('click', function () {
$.mobile.changePage("#shop-home", {
transition: "slide"
});
});
}
What I do is try to all the setupMainNav() function every-time a page changes using the .on('pagecreate') but only the first page that is loaded which has the #show_link and #shop_link elements with those ID's and of course those are the only two.
What are best practices for setting up navigation that is controlled via the JS and not the <a href>
Disclaimer: these are a few of what I think of as "best practices." Others may disagree; YMMV. Also this is assuming you don't want to use libraries or frameworks like Vue.js or React.js, which in general will do things quite differently. Depending on circumstances these libraries can have both advantages and drawbacks.
But within those limits, the general idea is this:
Keep the event handler generic, so that one function can do multiple things.
Pass in stuff that differs between links as attributes. This keeps things related to the activity together at the link.
I like to attach the event listener higher up in the DOM and then handle the events as they bubble. In this case we're attaching the event to the ul tag, and catching any click events that bubble up from a tags. IMHO this has a few advantages:
if you mutate the list, new links will automatically use the current event handler.
you only have one event handler attached to the DOM, instead of 3 (however many a tags you have)
this also gives you the chance to add other event listeners directly to specific a tags if you want to do something special before (or instead of) the default action. Because events attached directly happen first, and then the event bubbles. If you want it to happen instead of, you would just call e.stopPropagation() to prevent the event from bubbling.
Also what I've done sometimes in the past is to have a single generic page with header and navbar, and then load the main content div via ajax. This has the very visually pleasing effect that when you go to a different page the navbar stays put, and doesn't reload. You could easily do this in the example code below, if changePage was doing an XHR/fetch, and then loading the contents into a main content div.
In this greatly simplified example, I show how we can use the href, innerText, and a data attribute to do different things depending on which link is clicked. Of course you can do as much (or as little) as you want/need in this regard.
$('ul.navbar').on('click', 'a', function(e) {
var t = e.target;
var info = t.dataset.info || '';
console.log("click " + t.innerText + ' ' + info);
$.mobile.changePage(t.href, {
transition: "slide"
});
e.preventDefault();
return false;
});
// stub of $.mobile.changePage
$.mobile = {
changePage: function(href, opts) {
console.log('changePage', href);
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class='navbar'>
<li>HOME</li>
<li>ARTIST</li>
<li>SHOW INFO</li>
</ul>
Not sure if I'm doing this right. I have a menu that toggles between open and close. Now I want a button to show up if the menu hasClass("open");. and I would like to remove the class once the class open is gone.
Here is the HTML part;
<nav>
<a class="closed"><i class="fa fa-bars"></i>Menu</a>
<ul>
<li>Menu items</li>
</ul>
<div class="close-btn">
<i class="fa fa-times" aria-hidden="true"></i>
</div>
</nav>
The HTML works, so this is not that important, the important part is that the elements are: nav, a, closed.
Now for the jQuery part;
$(document).ready(function(jQuery) {
if ($("nav a").hasClass("open")) {
$(".close-btn").addClass('show-me-the-button');
} else {
$(".close-btn").removeClass('show-me-the-button');
}
});
But this doesn't work. I've searched stackoverflow but all gave me this code... not sure why it isn't working. I get no script errors... any help?
You check classes only on initial page load. Where do you change open class? You should move this code in that place.
User - oryol is correct
Try to put your code inside a handler like this:
$(document).ready(function(jQuery) {
$('nav a').on('click', function(e) { // <----------- Click Handler (jQuery)
// Use $(this) to access current clicked element
if ($(this).hasClass("open")) {
$(".close-btn").addClass('show-me-the-button');
} else {
$(".close-btn").removeClass('show-me-the-button');
}
})
});
See more about Click Handler in jQuery
Hope this helps!
I have small dropdown profile menu with logout button etc. I need to show the menu when I click on the button and hide it when i click anywhere on page or on the button as well.
<div id='menu'>
<ul>
<li class='has-sub'> <a class="testbutton" id="userButton" onclick="dropdown()" href="#">
<span id="buttonText">User name</span> <span id="triangleDown">▾</span>
</a>
<ul id="submenu">
<li class='has-sub'><a href='#'><span>Change password</span></a>
</li>
<li class='has-sub'><a href='logout.php?action=0'><span>Logout</span></a>
</li>
</ul>
</li>
</ul>
</div>
I used JavaScript. At this time menu is displayed on hidded only when I click on profile button. I also know how to start function using something like document.ready.
My not working code:
function dropdown() {
if ($('#submenu').css('visibility') == 'hidden') {
$('#submenu').css('visibility', 'visible');
} else {
$('#submenu').css('visibility', 'hidden');
}
};
$(document).click(function (event) {
if ($('#submenu').css('visibility') == 'visible') {
$('#submenu').css('visibility', 'hidden');
}
});
But when I combine this methods it does not works. So when I clicked on the button to open menu, nothing happened.
Sorry for my English :)
Thanks for help in advance.
This has partly to do with something called event propagation. Put simply, this means that click events will register not only on the clicked element, but also on any parent or ancestor elements of that element.
So if you click a DIV, the event will also be registered on the BODY, because the DIV is inside the BODY. Put abstractly, if a kitchen is the scene of a crime, then the apartment that houses that kitchen is also the scene of a crime. One is inside the other.
This is prevented by preventing propagation - in jQuery, by running the stopPropagation() method of the evt object that is automatically passed to your event handler.
In any case, your situation can be greatly simplified.
var menu = $('#menu'), but = $('#menu_button');
$(document).on('click', '*', function(evt) {
evt.stopPropagation(); //<-- stop the event propagating to ancestral elements
if ($(this).is(but)) //<-- on button click, toggle visibility of menu
menu.toggle();
else if (!$(this).closest(menu).length) //<-- on click outside, hide menu
menu.hide();
});
Assumption: I have assumed that the toggler button is targetable via the selector '#menu_button'. Update this as required. Also, the code should run inside a DOM-ready handler.
The code listens for clicks to any element. If it's registered on the button, the visible state of the menu is toggled. If it's to an element outside of the menu, the menu is hidden. (If, in the latter case, the menu is already hidden, this will have no effect.)
Here's a working JS Fiddle that demonstrates the approach.
Try this:
$(function() {
$('.test-button').click(function(event) {
event.stopPropagation();
$('#submenu').toggle();
});
$('body').click(function() {
var submenu = $('#submenu');
if(submenu.is(":visible")) {
submenu.hide();
}
})
});
Im trying to create a false hover event for my site using jQuery...
I have created the following only all the child elements in my list now return false also as opposed to linking to the correct page...
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) {
$("ul.sf-menu li.i").click(function(e) {
e.preventDefault();
});
}
Has anybody an idea on an alternative method that could work?
HTML
<ul class="sf-menu"> <li>Home<li class="i">Weddings
<ul>
<li>Peel Suite</li>
<li>The Hall</li>
<li>The Grounds</li>
<li>Food & Drink</li>
<li>Pricing</li>
</ul>
</li>
well. without HTML its kind of hard to tell. But you are stopping the default behavior of the browser when the user clicks on the li (and therefor also its children, which I suppose is an anchor/link).
you could check if its a link or an anchor on click and handle it differently;
$("ul.sf-menu li.i").click(function(e) {
if (e.target.nodeName!=="A"){
e.preventDefault();
//do your hover code
}
else{
//do nothing, because the user wants the link to load
}
});
change youre selector so it only matches the first level of listpoints, also i dont see a class i so you might need to drop that from the selector aswell.
$("ul.sf-menu > li")
I have a small chunk of code, like this:
$("div.footerMenu li").click(
function () {
$("div.onScreen").hide();
$(this).children("div.onScreen").fadeIn('fast');
},function(){
$("div.onScreen").hide();
});//click
And when I click on <li> the div .onScreen shows nicely, but when i click on this div, that just showed up the functions is hiding in and showing again, but I don't want it to execute this function again. So my question is: How can I somehow "detach/exclude/hide" this div from Javascript?
update:
The thing is that with this method and with others with .one() the rest of menu is not working. There is the site with the problem here . I want this div that shows up stay there, when I click on it, but when I click on their items <li> I want to other div's (submenus) to show up (warning - big images on that site).
The html looks like this:
<div class="footerMenu"> <ul> <li>HOME<div class="onScreen"><div style="padding:50px;"><img src="fillTxt.png"></div></div></li> <li>PLENER<div class="onScreen"> <div style="padding:50px;"><img src="fillTxt2.png"></div></div> </li> <li>STUDIO<div class="onScreen"> <div style="padding:50px;"><img src="fillTxt.png"></div></div> </li> <li>INNE<div class="onScreen"> <div style="padding:50px;"><img src="fillTxt2.png"></div></div> </li> </ul> </div>
The simple solution is:
$('div.footerMenu li').unbind('click');
But should you have multiple click handlers on the selector, you may want to only remove one at a time. The way to do that is to store a reference to the function being passed:
function hideItem()
{
...code...
//unbind the click event
$(this).unbind('click', hideItem);
}
$('div.footerMenu li').click(hideItem);
If you want to handle an event only once, you can use the one() method:
$("div.footerMenu li").one("click", function() {
$("div.onScreen").hide();
$(this).children("div.onScreen").fadeIn("fast");
});
You can use .one():
$("div.footerMenu li").one('click', function(){
things_to_happen_only_once();
// unbinding happens automatically
});