How to slide tabs in and out together like a carousel - javascript

I'm trying to make the slides within jQuery UI tabs look as if they're next to each other and somewhat attached. I think I'll be able to achieve this by running the show and hide animations at the same time.
Currently jQuery slides the current panel out and then the next one. How can I slide out the current panel while at the same time slide in the next one?
$("#tabs").tabs({
hide:{effect:"slide", direction:"right"},
show:{effect:"slide", direction:"left"}
});
http://jsfiddle.net/CnEUh/2372/
I want to start both the hide: and show: effects at the same time rather than one after the other

Here's the version based on my original comment.
This keeps jQuery's tab system, but hides the existing tabs. New slidingTabs div contains the sliding tabs so they can be animated.
Update
As per request, the initial content remains as it was before.
function makeTabsIntoSlidingTabs($tabs) {
$tabs.find("div").wrapAll("<div style='display:none' />");
$tabs.append("<div class='slidingTabs' />");
$tabs.children("div").first().find("div").each(function(i) {
$tabs.find(".slidingTabs").append($("<div />").addClass("tab").html($(this).html()));
});
$tabs.tabs({
activate: function(event, ui) {
var tab = $tabs.tabs("option", "active");
$tabs.find(".slidingTabs div").first().animate({
marginLeft: (tab * -100) + '%'
}, 400, function() {});
}
});
}
makeTabsIntoSlidingTabs($("#tabs"));
.slidingTabs {
white-space: nowrap;
overflow-x: hidden;
}
.slidingTabs .tab {
width: 100%;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" />
<div id="tabs">
<ul>
<li>Tab 1
</li>
<li>Tab 2
</li>
<li>Tab 3
</li>
</ul>
<div id="tabs-1">
<p>Content for Tab 1</p>
</div>
<div id="tabs-2">
<p>Content for Tab 2</p>
</div>
<div id="tabs-3">
<p>Content for Tab 3</p>
</div>
</div>

I think the proper way to change the behavior of a jQuery's widget is to extends it.
This way the solution is extensible, leave room for customization while allowing the tabs to remain a ui.widget, preserving jQuery's styling and state control.
$(document).ready(function() {
// Clean whitespaces before creating tabs
$('#tabs').cleanWhitespace();
/* retains most of $.ui.tabs options, but now since both
* hide & show animations are combined there's a
* shared direction & duration
*/
$("#tabs").customSlideTabs({
direction: "left",
duration: 500
});
});
$.widget("nameSpace.customSlideTabs", $.ui.tabs, {
_toggle: function(event, eventData) {
var that = this,
toShow = eventData.newPanel,
toHide = eventData.oldPanel;
this.running = true;
var container = $(toHide.parent());
var originalContainerOverflow = container.css("overflow");
function complete() {
container.css("overflow", originalContainerOverflow);
eventData.newTab.closest("li").addClass("ui-tabs-active ui-state-active");
eventData.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active");
that.running = false;
that._trigger("activate", event, eventData);
}
// start out by hiding, then showing, then completing
if (toHide.length && toShow.length) {
if (!this.options.duration) this.options.duration = 300;
container.css({
"overflow": "hidden",
"white-space": "nowrap"
});
var fromX, toX;
if (this.options.direction == "right") {
toHide.appendTo(container);
fromX = "-100%";
toX = 0;
} else {
toShow.appendTo(container);
fromX = 0;
toX = "-100%";
}
toShow.css({
"width": "100%",
"box-sizing": "border-box",
"display": "inline-block",
"vertical-align": "top",
"position": "relative",
"left": fromX,
"white-space": "wrap"
});
toHide.css({
"width": "100%",
"box-sizing": "border-box",
"display": "inline-block",
"vertical-align": "top",
"position": "relative",
"left": fromX,
"white-space": "wrap"
});
toShow.animate({
"left": toX
}, {
duration: that.options.duration,
complete: function() {
toShow.attr("style", "display: block;");
}
});
toHide.animate({
"left": toX
}, {
duration: that.options.duration,
complete: function() {
toHide.attr("style", "display: none;");
complete();
}
});
} else {
toHide.hide();
toShow.show();
complete();
}
toHide.attr({
"aria-expanded": "false",
"aria-hidden": "true"
});
eventData.oldTab.attr("aria-selected", "false");
// If we're switching tabs, remove the old tab from the tab order.
// If we're opening from collapsed state, remove the previous tab from the tab order.
// If we're collapsing, then keep the collapsing tab in the tab order.
if (toShow.length && toHide.length) {
eventData.oldTab.attr("tabIndex", -1);
} else if (toShow.length) {
this.tabs.filter(function() {
return $(this).attr("tabIndex") === 0;
})
.attr("tabIndex", -1);
}
toShow.attr({
"aria-expanded": "true",
"aria-hidden": "false"
});
eventData.newTab.attr({
"aria-selected": "true",
tabIndex: 0
});
}
});
// Gratitues http://stackoverflow.com/a/2587356/1645830
$.fn.cleanWhitespace = function() {
textNodes = this.contents().filter(
function() {
return (this.nodeType == 3 && !/\S/.test(this.nodeValue));
})
.remove();
return this;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<div id="tabs">
<ul>
<li>Tab 1
</li>
<li>Tab 2
</li>
<li>Tab 3
</li>
</ul>
<div id="tabs-1" class="tab">
<p>Content for Tab 1</p>
</div>
<div id="tabs-2" class="tab">
<p>Content for Tab 2</p>
<p>Content for Tab 2</p>
</div>
<div id="tabs-3" class="tab">
<p>Content for Tab 3</p>
</div>
</div>
<div id="tabid"></div>
This is by no mean complete, since it only support sliding left & right and not the full set of animations from jQuery, but I think it's a good base to work on.

Try this out .Hope this is what you needed.i have used the css transition for the slide effect.
$(document).ready(function() {
$("#tabs").tabs({
beforeActivate: function(event, ui) {
var index = ui.newTab.find('a').attr('href');
var currentPage = $(index).index();
//530 is the width of the frame or you can say the overall width including padding and margin for the content tabs.
$('.inner').css('left', '-' + (currentPage) * 530 + 'px');
},
});
});
body {
background-color: #eef;
}
#tabs {
width: 95%;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
}
#maindiv {
position: relative;
overflow: hidden;
width: 530px;
}
.inner {
position: relative;
display: inline-flex;
height: 100%;
transition: -webkit-transition: left .6s ease-in-out;
transition: left .6s ease-in-out;
}
#tabs-1,
#tabs-2,
#tabs-3 {
outline: solid 5px red;
outline-offset: -5px;
float: left;
display: block !important;
width: 480px;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<div id="tabs">
<ul>
<li>Tab 1
</li>
<li>Tab 2
</li>
<li>Tab 3
</li>
</ul>
<div id="maindiv">
<div class="inner" style="left:0px;">
<div id="tabs-1">
<p>Content for Tab 1</p>
</div>
<div id="tabs-2">
<p>Content for Tab 2</p>
</div>
<div id="tabs-3">
<p>Content for Tab 3</p>
</div>
</div>
</div>
</div>
<div id="tabid"></div>
you can check the js fiddle Here.

This is NOT what you may be looking for, but you can always look for other solutions outside what jqueryui libraries gives you.
in this example I have removed the slide effect, I have wrapped your tabcontent divs into a container with nowrap and displayed them as inline-block so they are standing side by side even if you don't see them (overflow:hidden at the parent), then with little jquery adding and removing classes to this new container when you click on the tabs and a css transition you may have what you are looking for.
Ugly as hell imho but it's an example of a work around
$("#tabs").tabs({
hide:{
},
show:{
}
});
$('#ui-id-1').click(function() {
$('.container').removeClass("move1");
$('.container').removeClass("move2");
});
$('#ui-id-2').click(function() {
$('.container').addClass("move1");
$('.container').removeClass("move2");
});
$('#ui-id-3').click(function() {
$('.container').addClass("move2");
});
JSFIDDLE

It's not possible to achieve this effect, without changing tabs js script. You can use a workaround with beforeActivate method. Eg.:
$("#tabs").tabs({
hide:{effect:"slide", direction:"right"},
beforeActivate: function( event, ui ){ui.newPanel.show("slide", { direction: "left" });}
});
But then there's a problem with tabs positioning. I written quick workaround for this problem, but i think it's better solution to use some custom js. jsFiddle
$("#tabs").tabs({
hide: {
effect: "slide",
direction: "right"
},
beforeActivate: function(event, ui) {
setTimeout(function() {
ui.newPanel.css({
'position': 'absolute',
'width': '100%',
'top': ui.oldPanel.offset().top - 11
});
ui.newPanel.show("slide", {
direction: "left"
}, function() {
ui.newPanel.css({
'position': 'relative',
'width': 'auto',
'top': 0
});
});
}, 15)
}
});
body {
background-color: #eef;
}
#tabs {
width: 95%;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
position: relative;
overflow: hidden;
}
#tabs-1,
#tabs-2,
#tabs-3 {
outline: solid 5px red;
outline-offset: -5px;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<div id="tabs">
<ul>
<li>Tab 1
</li>
<li>Tab 2
</li>
<li>Tab 3
</li>
</ul>
<div id="tabs-1">
<p>Content for Tab 1
<br/>
</p>
</div>
<div id="tabs-2">
<p>Content for Tab 2</p>
</div>
<div id="tabs-3">
<p>Content for Tab 3</p>
</div>
</div>
<div id="tabid"></div>

Related

Menu slider with javascript/jquery

I'm trying to make a menu slider for a restaurant with two clickable menus, the lunch menu and the dinner menu. I don't want the menus opening in a new window, just a clean click and the wanted menu opens.
Here is the code I have so far, I know it needs a lot of work, I'm new to the javascript/jQuery world. Pure javascript would be cool but anything jQuery would work too.
If someone can help me and please explain what needs to be fixed so i can understand this more I would greatly appreciate it. Thank You. On codepen
let lunchContainer = document.querySelectorAll('div.lunchmenu');
dinnerContainer = document.querySelectorAll('div.dinnermenu');
function reset() {
for(let i = 0; i < lunchContainer.length; i++) {
lunchContainer[i].style.display = 'none';
dinnerContainer[i].style.display = 'none';
}
};
$('.lunch').click(function(event) {
reset();
$('.lunchmenu').addClass('active');
lunchContainer.style.display = 'block';
});
$('.dinner').click(function() {
reset();
$('.lunchmenu').removeClass('active');
});
$('.dinner').click(function(event) {
reset();
$('.dinnermenu').addClass('active');
// dinnerContainer.style.display = 'block';
});
$('.lunch').click(function() {
reset();
$('.dinnermenu').removeClass('active');
// dinnerContainer.style.display = 'block';
});
<div class="page">
<div class="header">
<div class="logoHeader">
<a href="index.html" >
<img class="crab" src="http://images.all-free-download.com/images/graphicthumb/vivid_hand_drawn_crab_decoration_pattern_vector_551463.jpg " alt="KingChef Krab logo">
</a>
<h1 id="titleHeader">
King Chef
</h1>
</div>
<nav class="menuHeader">
<a class="specMenu" href="about.html">about</a></li>
<a class="specMenu" href="team.html">team</a></li>
<a class="specMenu" href="menus/dinner.html">menu</a></li>
<a class="specMenu" href="#">news</a></li>
<a class="specMenu" href="#">hours</a></li>
<a class="lastMenu" href="#">reservations</a></li>
</nav>
</div>
<nav id="menuCategory">
<a class="menuStyles lunch" href="#lunch">lunch</a>
<a class="menuStyles dinner" href="#dinner">dinner</a>
</nav>
<div class="container">
<div class="lunchmenu">
<p>hehehfdsafhkalfj</p>
</div>
<div class="dinnermenu">
<p>hdhfsahf</p>
</div>
</div>
</div>
.lunchmenu {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
&.active {
display: block;
}
}
.dinnermenu {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
&.active {
display: block;
}
}
Notice how much code I removed! You don't need to set display if you're going to use an 'active' class to do that job and you don't need to define the behavior of a click on your buttons twice.
Also, if each menu has a container, you don't need to iterate over all the items inside of them to set their display to none, setting the parent container to none will suffice.
Hope that helps!
let lunchContainer = document.querySelectorAll('.lunchmenu'), // notice ',' instead of ';'
dinnerContainer = document.querySelectorAll('.dinnermenu');
$('.lunch').click(function(event) {
$('.dinnermenu').removeClass('active');
$('.lunchmenu').addClass('active');
});
$('.dinner').click(function() {
$('.lunchmenu').removeClass('active');
$('.dinnermenu').addClass('active');
});
.lunchmenu, .dinnermenu {
display:none;
}
.active {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="lunch">lunch</button>
<button class="dinner">dinner</button>
<div class="lunchmenu">
<h5>lunch menu yayyy</h5>
<p>item lunch 1</p>
<p>item lunch 2</p>
</div>
<div class="dinnermenu">
<h5>Dinner menu yayyy</h5>
<p>itemdinner 1</p>
<p>item dinner 2</p>
</div>

Adding and removing classes depending on other elements

So I have carousel with slides (works on fullPage.js):
<div id="myContainer">
<div class="section" data-anchor="skynet">
<div class="slide one" data-anchor="main">
Slide 1
</div>
<div class="slide two" data-anchor="about_us">
Slide 2
</div>
<div class="slide three" data-anchor="faq">
Slide 3
</div>
<div class="slide four" data-anchor="news">
Slide 4
</div>
</div>
</div>
And I have some blocks with backgrounds
<div class="bg-main" id="bgOne"></div>
<div class="bg-main" id="bgTwo"></div>
<div class="bg-main" id="bgThree"></div>
<div class="bg-main" id="bgFour"></div>
Slides swaps by adding class active to blocks with class .one, .two etc.
I try to add class to blocks with background depend on active slide. For example - if .slide.two has class .active, add class to block #bgTwo.
Here my current JS. It doesn't work:
<script type="text/javascript">
$(document).ready(function(){
if ( $('#myContainer .one').hasClass('active') ) {
$('.bg-main').removeClass('active');
$('#bgOne').addClass('active');
} else if ( $('#myContainer .two').hasClass('active') )
{
$('.bg-main').removeClass('active');
$('#bgTwo').addClass('active');
}
});
</script>
Use the callback onSlideLeave
Demo
$(document).ready(function() {
$('#fullPage').fullpage({
onSlideLeave: function(link, secIdx, sldIdx, dir, next) {
$('.test .bg-main').removeClass('active');
$('.test .bg-main').eq(next).addClass('active');
}
});
});
.slide {
text-align: center
}
.test {
position: fixed;
top: 75%;
right:calc(50% - 220px);
}
.bg-main {
height: 30px;
width: 100px;
background: grey;
display:inline-block;
text-align:center;
outline:1px solid #fff;
margin:0;
}
.one,
#bgOne.active {
background: #fc0;
}
.two,
#bgTwo.active {
background: #f00;
}
.three,
#bgThree.active {
background: #0f0;
}
.four,
#bgFour.active {
background: #00f;
}
<link href='https://cdn.jsdelivr.net/jquery.fullpage/2.9.4/jquery.fullpage.min.css' rel='stylesheet'>
<div id="fullPage">
<div class="section" data-anchor="skynet">
<div class="slide one" data-anchor="main">
Slide 1
</div>
<div class="slide two" data-anchor="about_us">
Slide 2
</div>
<div class="slide three" data-anchor="faq">
Slide 3
</div>
<div class="slide four" data-anchor="news">
Slide 4
</div>
</div>
</div>
<div class='test'>
<div class="bg-main active" id="bgOne">1</div>
<div class="bg-main" id="bgTwo">2</div>
<div class="bg-main" id="bgThree">3</div>
<div class="bg-main" id="bgFour">4</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://cdn.jsdelivr.net/jquery.fullpage/2.9.4/jquery.fullpage.min.js'></script>
So i found out that fullpage.js use event afterSlideLoad. So thats my solution:
<script type="text/javascript">
$(document).ready(function() {
$('#myContainer').fullpage({
anchors: ['skynet'],
menu: '#menu',
scrollingSpeed: 500,
normalScrollElements: '.modal',
scrollOverflow: true,
afterSlideLoad: function( anchorLink, index, slideAnchor, slideIndex){
var loadedSlide = $(this);
if(slideIndex == 0){
$('.bg-main').removeClass('active');
$('#bgOne').addClass('active');}
if(slideIndex == 1){
$('.bg-main').removeClass('active');
$('#bgTwo').addClass('active');}
if(slideIndex == 2){
$('.bg-main').removeClass('active');
$('#bgThree').addClass('active');}
if(slideIndex == 3){
$('.bg-main').removeClass('active');
$('#bgFour').addClass('active');}
}
})
});
</script>
Class is added only after the slide is changed, and not during the process itself. The background does not change as fast as I'd like, but this is the best thing I could achieve.
The perfect solution is to extend the fullpage.js to handle the feature.
This is a workaround:
<script type="text/javascript">
var updateClasses = function(){
var activeClass = 'active';
var eq = $('#myContainer').children(activeClass).eq();
var bgMain = $('.bg-main').removeClass(activeClass);
bgMain.eq(eq).addClass(activeClass);
};
$(document).ready(function(){
$(".fp-controlArrow").on("click.updateClasses", function(){
updateClasses();
});
});
</script>

How to set js function scroll let it don't exceed parent‘s bottom?

The html, js, css example is https://jsfiddle.net/t9mfmaa3/5/.
/* Latest compiled and minified JavaScript included as External Resource */
$(function() {
var $sidebar = $("#e"),
$window = $(window),
$offset = $sidebar.offset(),
$topPadding = 15;
$window.scroll(function() {
if ($window.scrollTop() > $offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - $offset.top + $topPadding
});
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});
/* Latest compiled and minified CSS included as External Resource*/
/* Optional theme */
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
body {
margin: 10px;
}
#c {
background-color: red;
height: 2400px
}
#e {
background-color: lightblue;
height: 600px
}
#b {
height: 2400px;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="a">
<div id="b" class="column col-xs-3 col-sm-3">
<div id="e" class="">
blue
</div>
</div>
<div id="c" class="center_column col-xs-9 col-sm-9">
red
</div>
</div>
</div>
</div>
I tried to make blue block not exceed yellow block which means the blue one always in yellow block. My idea is to set code to detect block yellow and block blue. But I didn't success. Anybody has any suggestion? Thanks
If you are already using bootstrap, you may as well use their affix javascript.
getbootstrap.com
Here is an example:
jsfiddle.net
$(function() {
var $sidebar = $("#e"),
$body = $('body'),
$parent = $('#b'),
topPadding = 15,
offset=$sidebar.offset();
$sidebar.affix({
offset: {
top: function() {
return $parent.offset().top - topPadding;
},
bottom: function() {
return $(document.body).height() - ($parent.offset().top + $parent.outerHeight());
}
}
});
});
You might notice it act a little weird and jumpy near the end, but that should go away when using it on a real site (instead of inside an iframe)

jQuery tabs - Enable and disable

I'm having a problem on how to disable tab 3 when the first button is clicked. When I click Activate 2nd tab, the 2nd tab will be enabled, but the 3rd tab will be enabled, too; it should be enabled when I click Activate 3rd tab.
What should I do?
<div class="tab-wrapper" id="tab-wrapper">
<div class="tab-header">
<ul class="tabs">
<li>Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
</ul>
</div>
<div class="tab_container">
<div id="tab1" class="tab_content">
this is tab 1
<button id="button2">Activate 2nd tab</button>
</div>
<div id="tab2" class="tab_content">
this is tab 2
<button id="button3">Activate 3rd tab</button>
</div>
<div id="tab3" class="tab_content">
This is tab3
</div>
</div>
</div>
</body>
<script type="text/javascript">
$(function() {
var activate = false,
tabLinks = $('.tabs a'),
tabContent = $('.tab_container').children();
tabLinks.eq(0).addClass('active'); // Add active class, could possibly go in markup
$('#tab2').hide();
$('#tab3').hide(); // Hide second tab
tabLinks.bind('click', function(e) {
e.preventDefault();
if(activate === true) { // Only do something if button has been clicked
var target = this.hash,
el = $(this);
tabLinks.filter('.active').removeClass('active');
el.addClass('active');
tabContent.hide(); // Hide all
$(target).show(); // Show selected
}
});
$('#button2').bind('click', function() {
activate = true; // Activate tab functionality
tabLinks.eq(1).trigger('click'); // Trigger a click on the second tab link
});
$('#button3').bind('click', function() {
activate = true; // Activate tab functionality
tabLinks.eq(2).trigger('click'); // Trigger a click on the third tab link
});
});
</script>
</html>
You can do something like this (using an array to know if the tab is already activated instead of only one boolean):
$(function() {
var activate = [true, false, false],
tabLinks = $('.tabs a'),
tabContent = $('.tab_container').children();
tabLinks.eq(0).addClass('active'); // Add active class, could possibly go in markup
$('#tab2').hide(); // Hide second tab
$('#tab3').hide(); // Hide second tab
tabLinks.on('click', function(e) {
e.preventDefault();
var idx = $(this).data('index');
if (activate[idx] === true) { // Only do something if button has been clicked
var target = this.hash,
el = $(this);
tabLinks.filter('.active').removeClass('active');
el.addClass('active');
tabContent.hide(); // Hide all
$(target).show(); // Show selected
}
});
$('button').on('click', function() {
var index = $(this).data('index');
activate[index] = true; // Activate tab functionality
tabLinks.eq(index).trigger('click'); // Trigger a click on the second tab link
});
});
* {
padding: 0;
margin: 0;
}
body {
margin: 30px;
}
.tab-wrapper {
width: 500px;
}
.tabs {
overflow: hidden;
list-style: none;
}
.tabs li {
float: left;
margin-right: 10px;
border: 1px solid #ccc;
border-bottom: 0;
}
.tabs a {
display: block;
padding: 5px;
width: 100px;
}
.tabs a.active {
background: #efefef;
}
.tab_container > div {
padding: 10px;
border: 1px solid #ccc;
}
button {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="tab-wrapper" id="tab-wrapper">
<div class="tab-header">
<ul class="tabs">
<li>step1</li>
<li>step2</li>
<li>step3</li>
</ul>
</div>
<div class="tab_container">
<div id="tab1" class="tab_content">
here is the list of the overview
<button data-index="1">Activate 2nd tab</button>
</div>
<div id="tab2" class="tab_content">
here is the list of the overview
<button data-index="2">Activate 3nd tab</button>
</div>
<div id="tab3" class="tab_content">
End
</div>
</div>
</div>
</body>
You can find the code on jsfiddle too :
https://jsfiddle.net/psLshz3u/

Do not run jQuery function when <a> tag clicked

I currently work with some jQuery, where i have got some problems.
I got this code
if ($(".accordion").length > 0) {
$(".accordion").each(function() {
var item = $(this).find(".accordion-text");
var height = item.outerHeight() + 20;
item.data("height", height + "px").css("height", "0px");
})
}
$(".accordion").on("click", function(e) {
foldOut($(this));
});
function foldOut(accordien) {
console.log(accordien);
var item = $(accordien).find(".accordion-text");
if ($(accordien).hasClass("accordion-open")) {
$(item).stop().transition({
height: '0px'
}, 500, 'in-out');
$(accordien).find(".accordionArrow").removeClass("accordionBgActive");
console.log($(accordien).find(".accordionArrow"));
} else {
$(accordien).find(".accordionArrow").addClass("accordionBgActive");
$(item).stop().transition({
height: item.data("height")
}, 500, 'in-out');
}
$(accordien).toggleClass("accordion-open");
}
But inside the div that is folding out, there may be an a tag, and when i click on the a tag it opens the link but also folds the div..
How can i get the div not to fold when the click is on an a tag?
HTML Where its "closed"
<div class="row">
<div class="overflow-hide rel">
<div class="accordion rel col-md-12 no-pad">
<div class="accordionHeaderDiv">
<h3>Test</h3>
<div class="accordion-header-teaser">
<p>TestTestTestTestTestTestTestTestTestTest</p>
</div>
</div>
<div class="accordion-text" style="height: 0px;">
<p>TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest</p>
<p>Test</p>
</div>
<div class="accordionArrow" style=" position: absolute; top: 0; cursor: pointer; right: 43px; height: 30px;"></div>
</div>
<div class="clearfix"></div>
</div>
</div>
Filter it out regarding event target:
$(".accordion").on("click", function(e) {
if(e.target.tagName.toLowerCase() === "a") return;
foldOut($(this));
});
As anchor can contains other contents, a more relevant way would be:
$(".accordion").on("click", function (e) {
if ($(e.target).closest('a').length) return;
foldOut($(this));
});

Categories

Resources