$(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><a href="#tabs-1">Tab 1</a>
</li>
<li><a href="#tabs-2">Tab 2</a>
</li>
<li><a href="#tabs-3">Tab 3</a>
</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>