Jquery click event repeats itself... sometimes - javascript

I'm having a weird (annoying) issue with a small jquery complement I'm coding. It is meant to control a small tabbed nav for content on a page, it's not meant to be a big deal. It currently has 3 buttons (tabs) and the system is meant to fade out the current tab and content and change to the new one when you click on any of the tabs.
jsfiddle
The HTML goes as follows:
<div class="fixed-wing-nav-cont">
<div class="fixed-wing-nav">
<div class="fixed-wing-nav-item" id="wing-nav-1">Features</div>
<div class="fixed-wing-nav-item" id="wing-nav-2">Benefits</div>
<div class="fixed-wing-nav-item active" id="wing-nav-3">Screenshots</div>
</div>
</div>
<div class="fixed-wing-tab-cont">
<div id="fixed-wing-tab-1">
Features Tab
</div>
<div id="fixed-wing-tab-2">
Benefits Tab
</div>
<div id="fixed-wing-tab-3" class="active">
<img src="images/screens.png" alt="screens" /> VIEW ALL
</div>
<div class="clear"></div>
</div>
And the CSS tied to it, just in case it might be important, is the following:
.fixed-wing-nav-cont{
width:100%;
border-bottom:1px solid #747474;
margin:20px 0;
}
.fixed-wing-nav{
display:table;
border-spacing:5px 0;
border-collapse:separate;
margin-left:-5px;
}
.fixed-wing-nav-item{
margin-right:40px;
height:40px;
color:#1c5fa9;
font-size:16px;
border-left:1px solid #1c5fa9;
border-top:1px solid #1c5fa9;
border-right:1px solid #1c5fa9;
text-align:center;
padding:0 10px;
display:table-cell;
vertical-align:middle;
cursor:pointer;
}
.fixed-wing-nav-item.active{
color:#fff;
background-color:#1c5fa9;
}
.fixed-wing-tab-cont{
position:relative;
width:100%;
height:400px;
}
.fixed-wing-tab-cont>div{
position:absolute;
top:0px;
left:0px;
width:100%;
height:400px;
overflow:hidden;
display:none;
}
.fixed-wing-tab-cont>div.active{
display:block;
}
.fixed-wing-tab-cont img{
border:none;
}
The Jquery complement is a very simple one - I know there are more elegant ways to do it, but I chose to go for what's meant to be faster to code, and simpler overall:
<script type="text/javascript">
$('#wing-nav-1').click(function(){
$('div.fixed-wing-nav-item').removeClass("active",function(){
$('#wing-nav-1').addClass("active");
});
$('#fixed-wing-tab-3').removeClass("active");
$('.fixed-wing-tab-cont>div').fadeOut("fast",function(){
$('#fixed-wing-tab-1').fadeIn("fast");
});
});
$('#wing-nav-2').click(function(){
$('div.fixed-wing-nav-item').removeClass("active",function(){
$('#wing-nav-2').addClass("active");
});
$('#fixed-wing-tab-3').removeClass("active");
$('.fixed-wing-tab-cont>div').fadeOut("fast",function(){
$('#fixed-wing-tab-2').fadeIn("fast");
});
});
$('#wing-nav-3').click(function(){
$('div.fixed-wing-nav-item').removeClass("active",function(){
$('#wing-nav-3').addClass("active");
});
$('#fixed-wing-tab-3').removeClass("active");
$('.fixed-wing-tab-cont>div').fadeOut("fast",function(){
$('#fixed-wing-tab-3').fadeIn("fast");
});
});
</script>
I'm loading Jquery 1.9 straight from the jquery site. Now, the issue I'm having is this: The page opens with the third tab loaded, no problems. If I click to go to the first tab, it works perfectly: The third tab fades out, the first one fades in and the "active" state from the tab button is moved from the third to the first one. If I then choose to go to the second tab it also works perfectly. However, if I try to go from any tab to the third one or from the third to the second it plays the animation twice, which makes no sense whatsoever: All three tabs are running the same code. I've been looking at the code over and over for an hour and I can't see why this is happening - Why does the first tab work perfectly, but the third one have such issues? I've tried removing the "active" state from all items in the HTML (thus making the tab/content start empty) and the issue still happens.
Can anyone help me here? This just doesn't make any sense to me :\

You were fading out all of your DIVs under the class .fixed-wing-tab-cont. So the content loading twice was really just the content being faded out and fading back in. You can exclude the DIV with the active class using the CSS 'not' selector in jQuery. Change
$('#wing-nav-3').click(function(){
$('div.fixed-wing-nav-item').removeClass("active",function(){
$('#wing-nav-3').addClass("active");
});
$('#fixed-wing-tab-3').removeClass("active");
$('.fixed-wing-tab-cont>div').fadeOut("fast",function(){
$('#fixed-wing-tab-3').fadeIn("fast");
});
});
to
$('#wing-nav-3').click(function(){
$('div.fixed-wing-nav-item').removeClass("active");
$('#wing-nav-3').addClass("active");
$('#fixed-wing-tab-3').removeClass("active");
$('.fixed-wing-tab-cont>div:not(.active)').fadeOut("fast");
$('#fixed-wing-tab-3').fadeIn("fast");
});
There is really no need for you to use callback functions in this instance. In fact, the removeClass method has no callback ability. You might have noticed that your active tab class wasn't being applied to the tabs you clicked on because of this.
Updated jsFiddle

You remove the 'active' class from the fixed-wing-nav-item divs correctly, but always remove the 'active' class from '#fixed-wing-tab-3', regardless of which of the tabs is active. If you removed the 'active' class from '.fixed-wing-tab-cont>div' and then add the 'active' class to the fixed-wing-tab you fadeIn it should work.

Related

How to apply Scrolling Animations when user starts scrolling a content

I need to Add some animations to an element when it is in viewport.
$(document).scroll(function(){
alert('How to animate with transitions left to right, top to bottom elements in my Structure ');
});
.main-container{
width:900px;
height:100%;
overflow:auto;
background:#00496d;
color:#fff;
}
#section1,#section2,#section3,#section4,#section5,#section6{
width:100%;
height:300px;
border:1px solid #fff;
margin:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-container">
<div id="section1"></div>
<div id="section2"></div>
<div id="section3"></div>
<div id="section4"></div>
<div id="section5"></div>
<div id="section6"></div>
</div>
Try Skrollr.js for animation on scroll. Although this is not updated for quite a long time, but you might give it a shot based on your requirement. It matches your ask above.
Try animation on scroll.
Download library of AOS ans add in your code. Here is the link where you can find library and also complete example how can use in your html class.
https://michalsnik.github.io/aos/

Is this correct markup - empty element OR use css/js to achieve same effect

I have a situation where I need to have a separator between 2 items as shown in the plunk. I could think of 2 methods for this to do as
1) Put an empty span between items and style it like separator
HTML:
<body>
<nav>
<section class="icon1">Icon1</section>
<span class="separator"></span>
<section class="icon2">Icon2</section>
</nav>
</body>
CSS:
nav {height:40px; background:yellow; width:300px; padding:0 10px;}
.icon1{ background:green; width:40px; height:100%; float:left;}
.icon2 {background:red; width:40px; height:100%; float:left;}
.separator{width:2px; height:100%; background:blue; float:left;}
2) Use :before psuedo selector for 2nd item and style it accordingly
HTML:
<body>
<nav>
<section class="icon1">Icon1</section>
<section class="icon2">Icon2</section>
</nav>
</body>
CSS:
nav {height:40px; background:yellow; width:300px; padding:0 10px;}
.icon1{ background:green; width:40px; height:100%; float:left;}
.icon2 {background:red; width:40px; height:100%; float:left;}
.icon2:before{content:""; border-left:2px solid blue; position:absolute; height:40px;}
Plunk - http://plnkr.co/edit/a26btGkR8p5xcQeSxJiV?p=preview
The plunk is for both options 1 and 2 combined, please un comment, if you would like to check.
Now, I have an action which is taken when user clicks on the 2nd item, which is a modal popover will open up and that 2nd item is highlighted i.e. it is over & above the backdrop.
If I use 2) above i.e. :before, and then I click on 2nd item, the modal popover shows, the 2nd item highlights but that separator also gets highlighted since technically it is inside that element. I do not want that separator to be highlighted, so, to make it appear like its faded, I am writing few lines of js to toggle its opacity ( on click of 2nd item) so it looks like its faded.
If I use 1) i.e. empty span there is no problem at all, no need to write js, it simply works fine.
So, my problem here is whether I
should use an empty span
OR
use :before and do some js
Which one would be semantically correct and also which one would be less burden on page.
I would use the 2nd solution, since the separator is probably not necessary for a (probably handicapped) user to understand the context.
Both ways are semantically correct .
i would recommend using the
<span class="separator"></span> method so that you can move your second icon with out worrying about the separator positioning .
for sure the ::before is more performance consuming ( definitely not noticeable )
remember that you also can use borders to make easy simple separators .

Two scrollbar using the same css

I'm using custom scrollbar, add one scrollbar is very easy, but if I want to add second they twice use one mCustomScrollbar.css I don't know how to change that second div. I was looking on code on demo custom scrollbar but this just fail.
JQUERY
(function($){
$(window).load(function(){
$(".suwak").mCustomScrollbar();
});
})(jQuery);
HTML
<link href="scrollbar/jquery.mCustomScrollbar.css" rel="stylesheet" type="text/css" />
<script src="scrollbar/jquery.mCustomScrollbar.concat.min.js"></script>
<div class="suwak"> content with first scrollbar </div>
<div class="suwak2"> content with second scrollbar </div>
Some simply CSS
.suwak{
position:relative;
width:475px;
height:300px;
background-color: #000e1b;
color: white;
overflow:hidden
margin-top:160px;
margin-left: 15px;
}
Just add another class on div with class="suwak", this will run your scrollbar and your second class will help override your first class. In css you are saying, if something has both classes, use new style. In css your selector would be .suwak.suwak2, no space between classes in css.
<div class="suwak"> content with first scrollbar </div>
<div class="suwak suwak2"> content with second scrollbar </div>
.suwak{
position:relative;
width:475px;
height:300px;
background-color: #000e1b;
color: white;
overflow:hidden
margin-top:160px;
margin-left: 15px;
}
.suwak.suwak2 {
/*new stile*/
}
Why don't you use second class as well? is it something that you don't know how many DIVs will be there to have same scrollbar?
If it is limited to 2 only, then try
(function($){
$(window).load(function(){
$(".suwak").mCustomScrollbar();
$(".suwak2").mCustomScrollbar();
});
})(jQuery);
Or you can mention same class for second DIV as well. I have suggested this as per my observation of the code you posted.

Scrolling the page causes issues to buttons

I just finished a website, everything was working fine (what I thought)
Until I discover a huge BUG that couldn't fix:
I have a navigation BAR (png file) and added on it buttons (simple DIVs elements), When the page is openned 1st, all is fine, but if you scroll the page a bit, the buttons aren't working as they should.
Please check this link: (scroll the page a bit down and you'll notice that button aren't interacting anymore)
http://www.genius-solutions.net/GSIS/index.html
But if you move the cursor a bit above the buttons, you'll find them:
(HTML - JavaScript)
here the CSS part:
#btn {position:absolute;left:0px;top:0px;z-index:4;}
#btn1 {position:absolute;left:80px;top:280px;width:140px;height:35px;background:#DDE6E3;opacity:0.0;cursor:pointer;}
#btn2 {position:absolute;left:230px;top:280px;width:140px;height:35px;background:#DDE6E3;opacity:0.0;cursor:pointer;}
#btn3 {position:absolute;left:380px;top:280px;width:140px;height:35px;background:#DDE6E3;opacity:0;cursor:pointer;}
#btn4 {position:absolute;left:530px;top:280px;width:140px;height:35px;background:#DDE6E3;opacity:0;cursor:pointer;}
#btn5 {position:absolute;left:680px;top:280px;width:140px;height:35px;background:#DDE6E3;opacity:0;cursor:pointer;}
#btn6 {position:absolute;left:830px;top:280px;width:140px;height:35px;background:#DDE6E3;opacity:0;cursor:pointer;}
#html, body {
background:#002a4c;
overflow:scroll;
width:1024px;
height:768px;
margin: 20px auto; /* center */ padding: 20px;
}
and here the HTML part:
<body >
<div id = 'applet' home='579' services='1437' solutions='1192' partners='100' aboutus='654' contacts='216'>
<div id='applet_t'>
<div id='btn'>
<div id='btn1'></div>
<div id='btn2'></div>
<div id='btn3'></div>
<div id='btn4'></div>
<div id='btn5'></div>
<div id='btn6'></div>
</div>
</div>
<div id='inf'></div>
</div>
</body>
Your issue lies in IMO very improper use of absolute positioning of your elements. As soon as you scroll the page the location of the actual "hit" placeholder moves with the page but not your background.
Test case: try to move your page up a little bit and you will be able to "click" above the actual buttons.
Unless you have a good reason for absolutely positioned element use static == default positioning for most of your elements.

javascript to overlay a modal popup that is center aligned

want to know Simply the javascript to overlay a div on centre of the page.
Just want to use plain java script to show and hide a div on the center of the page with "Please wait..." message and disable the background. Also this div shoud show on top of the other content of the page.
My div looks like this
<div id='mydiv' style="display:none;" ><img src="myimg.gif" /> Please Wait... </div>
On click of a button , I want to show the div content center aligned on the page.
I do not want to use jquery,extjs,,etc to achieve this.
I have seen a few examples on the web with lot of other features added to a modal popup, just looking for something simple and clean.The bare minimum JS required to do this.
The div you want to display needs to have an ID:
<div id="loaderdiv">
Then in your javascript, you display this div with the following code:
document.getElementById("loaderdiv").style.display = '';
Thats the bare minimum you'll need.
Centering the image can be done using CSS:
<div style="position:absolute;top:50%;left:50%;margin-top:-[imgheight/2]px;margin-left:-[imgwidth/2]px">
<div class="overlay_msg" id="overlay_msg" style="width:350px; height:100px; background-color:#ffffff; margin-left:300px; margin-top:20%; visibility:hidden; z-index:201; position:fixed; padding:15px; text-align:center;">
example.com<br />
</div><!--overlay_msg-->
<div class="my_overlay" id="my_overlay" style="background-color:#000000; opacity:.7; position:fixed; z-index:200; width:100%; height:100%; margin:0px; padding:0px; visibility:hidden;" onclick="hideMyOverlay()">
</div><!--my_overlay-->
<script type="text/javascript">
function showMyOverlay()
{
document.getElementById('my_overlay').style.visibility='visible';
document.getElementById('overlay_msg').style.visibility='visible';
}
function hideMyOverlay()
{
document.getElementById('my_overlay').style.visibility='hidden';
document.getElementById('overlay_msg').style.visibility='hidden';
}
</script>

Categories

Resources