Prevent page jump on tab click JS - javascript

I have a couple of tabs with varying heights. How do I prevent the page from jumping to the top of the container when I click on a tab link?
JSFiddle
http://jsfiddle.net/q1tdsar1/1/
Steps to reproduce issue: Click on tab 3, scroll down as if reading the content of tab 3 then click tab 1. Boom > Page Jump!
Here's my JS:
$('#tabs div.tab').hide();
$('#tabs div.tab:first').show();
$('#tabs ul li:first').addClass('active');
$('#tabs ul li a').click(function(){
$('#tabs ul li').removeClass('active');
$(this).parent().addClass('active');
var currentTab = $(this).attr('href');
$('#tabs div.tab').hide();
$(currentTab).show();
return false;
});
Here's the HTML
<div id="tabs">
<ul class="nav">
<li>Tab 1</li>
<li>Tab 2</li>
<li>Tab 3</li>
</ul>
<div id="tab-1" class="tab">Some content</div>
<div id="tab-2" class="tab">Some longer content</div>
<div id="tab-3" class="tab">Some even longer content</div>
</div>
Here's CSS:
#tabs ul.nav {
float: left;
width: 500px;
}
#tabs li {
margin-left: 8px;
list-style: none;
}
* html #tabs li {
display: inline;
}
#tabs li,
#tabs li a {
float: left;
}
#tabs ul li.active {
border-top:2px #FFFF66 solid;
background: #FFFFCC;
}
#tabs ul li.active a {
color: #333333;
}
#tabs div.tab {
background: #FFFFCC;
clear: both;
padding: 15px;
}
#tabs ul li a {
text-decoration: none;
padding: 8px;
color: #000;
font-weight: bold;
}

You may need to use an equal height for all the tabs you have so far. So a script might be helpful, as this is not the page jump that happens, as you already have return false in the place of event.preventDefault();.
TabDivHeight = 0;
$('#tabs div.tab').each(function () {
$(this).show();
if ($(this).height() > TabDivHeight)
TabDivHeight = $(this).height();
$(this).hide();
});
$('#tabs div.tab').height(TabDivHeight);
Fiddle: http://jsfiddle.net/342fsu8o/
Or if you would prefer a CSS version, I would say, go for this:
#tabs div.tab {
background: #FFFFCC;
clear: both;
padding: 15px;
max-height: 200px;
overflow: auto;
}
Fiddle: http://jsfiddle.net/jv3bmtof/
Or if you prefer a smooth transition, you may use slideUp() and slideDown():
$('#tabs ul li a').click(function () {
$('#tabs ul li').removeClass('active');
$(this).parent().addClass('active');
var currentTab = $(this).attr('href');
$('#tabs div.tab').slideUp();
$(currentTab).slideDown();
return false;
});
Fiddle: http://jsfiddle.net/tdxyLvLs/

Related

jQuery .hover() or .mouseleave() not working on chrome

Problem description:
In my menu when .mouseenter() the menu opens and when .mouseleave() it closes, but if i click a lot , the .mouseleave() event is executed.
This only happened on chrome browser.
I have other .click() events inside my menu, but every click I made, the .mouseleave() event is execute.
$(document).ready(function() {
$("#nav1 li").hover(
function() {
$(this).find('ul').slideDown();
},
function() {
$(this).find('ul').slideUp();
});
});
#nav1 a {
color: #FFFFFF;
}
#nav1 li ul li a:hover {
background-color: #394963;
}
div ul li ul {
background-color: #4a5b78;
list-style: none
}
#nav1 > li > a {
padding: 16px 18px;
display: block;
border-bottom: 2px solid #212121;
}
#nav1 li ul li a {
padding: 10px 0;
}
div {
background-color: #000000;
background-color: #343434;
width: 280px;
}
/* Hide Dropdowns by Default */
#nav1 li ul {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<ul id="nav1">
<li>Hover here and infinite click
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 2
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
</ul>
<div>
Try click "Hover here and infinite click" to see this problem.
EDIT:
As you guys said, the problem occurs in this example.
Here is a video: Video link
When you click many times the browser has lost the element reference, try this example:
<div id="container">
<ul id="nav1">
<li>Menu Heading 1
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 2
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 3
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
</ul>
<div>
Css
ul,
li,
a {
padding: 0px;
margin: 0px;
}
.show {
display: block !important;
}
#nav1 a {
color: #FFFFFF;
}
#nav1 li ul li a:hover {
background-color: #394963;
}
div ul li ul {
background-color: #4a5b78;
list-style: none
}
#nav1 > li > a {
background-color: #343434;
padding: 16px 18px;
text-decoration: none;
display: block;
border-bottom: 2px solid #212121;
background: linear-gradient(top, #343434, #111111);
}
#nav1 li ul li a {
padding: 10px 0;
padding-left: 30px;
text-decoration: none;
display: block;
}
div {
background-color: #000000;
background-color: #343434;
width: 280px;
}
/* Hide Dropdowns by Default */
#nav1 li ul {
display: none;
}
JS
$(document).ready(function() {
$("#nav1 li").hover(
function(e) {
let ulMenu = $(this).find('ul');
ulMenu.addClass('show');
//$(this).find('ul').slideDown();
},
function(e) {
if(e.relatedTarget){
let ulMenu = $(this).find('ul');
ulMenu.removeClass('show');
} else {
console.log('fail ');
}
//$(this).find('ul').slideUp();
});
});
Codepen Example Works
You can add a stropPropagation in your click event.
$("#nav1 li").click(
function(e){
e.stopPropagation();
});
maybe the event is getting lost in the process, try to verify it, and if so set the actual element.
see this: https://api.jquery.com/event.relatedTarget/

how do you change a active class in html

i have a navigational bar at the side of my website but the problem is that when i change the tab in the navigational bar the active class does not change here is my code
<!DOCTYPE html>
<html>
<body style="background-color:yellow">
<font color="red"><div align="center"><h1>About</h1></div></font>
<head>
<style>
body {
margin: 0;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 25%;
background-color: #875050;
position: fixed;
height: 100%;
overflow: auto;
}
li a {
display: block;
color: #000;
padding: 8px 16px;
text-decoration: none;
}
li a.active {
background-color: #4CAF50;
color: white;
}
li a:hover:not(.active) {
background-color: #555;
color: white;
}
</style>
</head>
<body>
<ul>
<li><a class="active" href="prodject.htm">Home</a></li>
<li>News</li>
<li>Contact</li>
<li>About</li>
</ul>
</body>
</html>
and here is my java script code
$(".nav li").click(function() {
if ($(".nav li").removeClass("active")) {
$(this).removeClass("active");
}
$(this).addClass("active");
});
is there any way to fix this
You don't have nav class in HTML
<ul class="nav">
<li><a class="active" href="prodject.htm">Home</a></li>
</ul>
You don't need if, directly use selector with the method.
$(".nav li").click(function() {
$(".nav li.active").removeClass("active");
$(this).addClass("active");
});
OR,
$(".nav li").click(function() {
$(this).siblings(".active").removeClass("active");
$(this).addClass("active");
});
You don't have a nav class in your dom tree. Add to ul element class attribute with nav value:
<ul class="nav"></ul>
make sure you also have the class attribute for those a tags but also maybe you target the a tag and not nav li
$("a").click(function() {
$(this).siblings("active").removeClass("active");
$(this).addClass("active");
});
You do not have added nav class to ul tag use this code <ul class="nav"></ul> and make changes in jquery use below jquery code.
$(".nav li").click(function() {
$(".nav li.active").removeClass("active");
$(this).addClass("active");
});

Nav button highlight works in desktop browser, but not in android mobile browser

Alright so I'm using jQueryMobile, jQuery/JavaScript and CSS to make a navigation bar that allows you to select an option from the top UL tree (horizontal nav bar) and then also select an option from the resulting submenu while the option from the parent ul tree is still highlighted.
This works in a desktop browser and in this jsfiddle I just created (at the bottom); however, once I'm in a mobile browser (Android Internet or Chrome Mobile), the parent ul no longer stays highlighted.
Why?
<div data-role="page" data-theme="a" id="home">
<div data-role="header" data-position="fixed">
<nav id="navbar" data-role="navbar">
<ul>
<li class="active"><a class="ui-btn-active" href="#">Real-Time</a>
<ul class="secondLvl">
<li>Choice 1</li>
<li>Choice 2</li>
<li>Choice 3</li>
<li class="lastNav"><a></a></li>
</ul>
</li>
<li>Database Functions
<ul class="secondLvl">
<li>Another Choice 1</li>
<li>Another Choice 2</li>
<li class="lastNav"><a></a></li>
</ul>
</li>
<li>Settings/Configuration
<ul class="secondLvl">
<li>Logout</li>
<li>A Third Choice 1</li>
<li>A Third Choice 2</li>
<li>A Third Choice 3</li>
<li class="lastNav"><a></a></li>
</ul>
</li>
</ul>
</nav>
</div>
<div data-role="main" class="ui-content">
</div>
<div data-role="footer" data-position="fixed">
<h1>
Home
</h1>
</div>
</div>
CSS:
#home
{
background-color: #5f6975;
overflow: hidden;
}
#navbar > ul {
position: relative;
}
#navbar ul ul {
display: none;
background: #5f6975;
border-radius: 0px;
padding: 0;
position: absolute;
top: 100%;
left: 0;
width: auto;
bottom: 1000px;
}
#navbar ul ul li {
float: left;
border-top: 1px solid #6b727c;
border-bottom: 1px solid #575f6a;
position: relative;
width: 100%;
}
.ui-navbar li:last-child .ui-btn {
margin-right: 0px !important;
}
.lastNav a {
height: 100vh;
pointer-events: none;
}
#navbar ul ul li a.active {
background: #4b545f;
}
#navbar ul ul ul {
position: absolute;
left: 100%;
top: 0;
}
#navbar ul li.active > ul {
display: block;
}
#navbar ul li {
float: left;
}
#navbar ul li.active {
background: #4b545f;
background: linear-gradient(top, #4f5964 0%, #5f6975 40%);
background: -moz-linear-gradient(top, #4f5964 0%, #5f6975 40%);
background: -webkit-linear-gradient(top, #4f5964 0%,#5f6975 40%);
}
#navbar ul li a {
display:block;
padding: 25px 40px;
text-decoration: none;
}
JavaScript/JQuery:
//Clear Text Fields
$(document).on("pagehide", function (e){
$(e.target).remove();
});
//Setup Side Navbar
$(document).on("pagecreate", "#home", function(){
var navItems = $("#navbar > ul > li");
var subWidth = 100 / navItems.length;
$("#navbar > ul > li").each(function( index ) {
$(this).find("ul").each(function(i) {
var top = (i + 1) * 100;
$(this).css({"position": "absolute",
"width": subWidth + "%",
"top": top + "%"});
});
});
});
//Make Side Navbar stick
$(document).on('pagebeforeshow','#home', function(event){
$('#navbar ul li').on('click', function () {
//removing the previous selected menu state
$('#navbar ul li.active').removeClass('active');
//is this element from the second level menu?
if($(this).closest('ul').hasClass('secondLvl'))
{
$(this).parents('li').addClass('active');
} //end if
//otherwise just highlight the element
else
{
$(this).addClass('active');
} //end else
})
$('ul').find('a').on('click', function() {
$(this).closest('ul').find('a').removeClass('ui-btn-active');
if($(this).closest('ul').hasClass('secondLvl'))
{
$(this).addClass('ui-btn-active');
}
})
})
Here's my JSFiddle: https://jsfiddle.net/LLx7vgjo/8/
Try using vclick event instead click. The jQuery Mobile "vclick" event handler simulates the "onclick" event handler on mobile devices. I hope this helps!

Nested UL Height

I have a menu with nested UL's to work as a drop down menu. In the drop down I have another nested UL with LI's that are pragmatically generated so I don't know how many are going to be in their.
I was trying to set the height of the second UL on load so that I can put a border around the dropdown.
HTML:
<ul>
<li>1</li>
<li>2
<ul>
<li>2a
<ul class="submenu">
<li>2a1</li>
<li>2a2</li>
<li>2a3</li>
<li>2a4</li>
<li>2a5</li>
</ul>
</li>
<li>2b
<ul class="submenu">
<li>2b1</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
<li>2b2</li>
</ul>
</li>
</ul>
</li>
<li>3</li>
</ul>
CSS:
ul {
list-style-type: none;
}
ul li {
display: inline-block;
/*float: left;*/
width: 100px;
}
ul li:hover {
background-color: #cc0505;
color: white;
}
ul li ul {
/*visibility: hidden;*/
position: absolute;
padding: 0px;
border: 2px solid black;
/*min-height:120px;*/
}
ul li:hover ul {
visibility: visible;
}
ul li ul li {
/*display: inline;
float: left;*/
color: black;
}
ul li ul li:hover {
background-color: white;
color: black;
}
ul li ul li ul {
border: none;
min-height:0px;
}
ul li ul li ul li {
display: block;
/*float: none;*/
}
ul li ul li ul li:hover {
background-color: #cc0505;
color: white;
}
I have tried using $('ul ul ul').each and $('ul ul ul').next() to loop through any UL on the third level but it only seems to be picking up the first occurrence.
A jsfiddle I set up with my code and a few attempts I have made to get this right. http://jsfiddle.net/kZ236/2/
the problem is, that height() always takes the height of the first element of the set, no matter what you do before calling that.
using each() together with a Math.max will work
http://jsfiddle.net/kZ236/3/
your code with next() didn't work as the ul didn't had a next element. next() is no iterator through the set of $('ul ul ul') but getting the next sibbling in the dom tree.
Try this:
$(document).ready(function () {
$('#nav>li>ul').each(function(){
var maxHt=0;
$(this).find('.submenu').each(function(){
var bottomPosition=$(this).height() +$(this).position().top
maxHt= bottomPosition>maxHt ? bottomPosition : maxHt;
});
$(this).height( maxHt)
})
})
DEMO

Add 2nd sub nav to accordion style menu

I'm looking to have an additional subnav to this accordion menu. I tried to add a child element to the nav ul li, but that didn't seem to work. Ideally, I would like to be able to list web projects under "web" and print under "print".
FIDDLE: http://jsfiddle.net/schermerb/rGMAu/1/
.header button {
cursor:pointer;
float:right;
padding:5px;
margin:10px 10px;
border:none;
border:1px solid #ececec;
background:#444;
color:#ececec;
}
.nav {
text-align:center;
background:#444;
}
.nav ul li {
text-transform:capitalize;
display:block;
border-bottom:1px solid #ececec;
}
.nav a {
display:block;
padding:10px;
color:#ececec;
}
.nav a:hover {
background:#029b9d;
color:#ececec;
}
<button id="show">Menu <span>+</span> <span style="display:none;">-</span>
</button>
<div class="clear"></div>
</div>
<div class="nav">
<ul>
<li>Home
</li>
<li>About
</li>
<li>Web
</li>
<li>Print
</li>
</ul>
</div>
I have updated your js
$('.nav, .nav li ul').hide();
$('#show').click(function () {
$(".nav").toggle();
$("span").toggle();
});
$('.nav li').click(function(){
$(this).children('ul').toggle();
});
Updated jsFiddle File
Adding a child element was the right path.
http://jsfiddle.net/jonigiuro/rGMAu/2/
<li>Web
<ul class="sub">
<li class="item">item1</li>
<li class="item">item2</li>
</ul>
</li>
You hide the child element by default, and when you hover on the parent, you show the it:
ul li:hover ul
Here's the revelant css for your case:
.nav ul li ul {
color: red;
margin: 0;
padding: 0;
display: none;
}
.nav ul li:hover ul {
display: block;
}
.nav ul li ul li {
padding: 10px 0;
}

Categories

Resources