jQuery 选项卡 - 非活动选项卡中的内容跨越整个页面,在页脚下方创建白色 space
jQuery tabs- content in non active tab spanning entire page creating white space below footer
我正在使用以下代码创建一个选项卡式框。有一个包含很多内容的选项卡,当该选项卡未处于活动状态时,页脚下方会出现一大堆白色 space。本质上,内容在不活动时并没有真正隐藏,这是我需要它做的。我已经包含了基本代码和 js 脚本。
我尝试设置高度和溢出来滚动,但不是很满意。非常感谢任何帮助。
参考框架代码如下:
<div class="product-collateral">
<ul class="tabset">
<li class="active"><a href="#tab1">Tab 1</a></li>
<li><a href="#tab2">Tab 2</a></li>
<li><a href="#tab3">Tab 3</a></li>
<li><a href="#tab4">Tab 4</a></li>
<li><a href="#tab5">Tab 5</a></li>
<li><a href="#tab6">Tab 6</a></li>
<li><a href="#tab7">Tab 7</a></li>
</ul>
<div class="box-collateral tab-content">
<div id="tab1">
</div>
<div id="tab2">
</div>
<div id="tab3">
</div>
<div id="tab4">
</div>
<div id="tab5">
</div>
<div id="tab6">
</div>
<div id="tab7">
</div>
</div><!-- /box-collateral tab-content -->
</div><!-- /product-collateral -->
这是 js 脚本
/*
* jQuery Tabs plugin
*/
;(function($){
$.fn.contentTabs = function(o){
// default options
var options = $.extend({
activeClass:'active',
addToParent:false,
autoHeight:false,
autoRotate:false,
checkHash:false,
animSpeed:400,
switchTime:3000,
effect: 'none', // "fade", "slide"
tabLinks:'a',
attrib:'href',
event:'click'
},o);
return this.each(function(){
var tabset = $(this), tabs = $();
var tabLinks = tabset.find(options.tabLinks);
var tabLinksParents = tabLinks.parent();
var prevActiveLink = tabLinks.eq(0), currentTab, animating;
var tabHolder;
// handle location hash
if(options.checkHash && tabLinks.filter('[' + options.attrib + '="' + location.hash + '"]').length) {
(options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass);
setTimeout(function() {
window.scrollTo(0,0);
},1);
}
// init tabLinks
tabLinks.each(function(){
var link = $(this);
var href = link.attr(options.attrib);
var parent = link.parent();
href = href.substr(href.lastIndexOf('#'));
// get elements
var tab = $(href);
tabs = tabs.add(tab);
link.data('cparent', parent);
link.data('ctab', tab);
// find tab holder
if(!tabHolder && tab.length) {
tabHolder = tab.parent();
}
// show only active tab
var classOwner = options.addToParent ? parent : link;
if(classOwner.hasClass(options.activeClass) || (options.checkHash && location.hash === href)) {
classOwner.addClass(options.activeClass);
prevActiveLink = link; currentTab = tab;
tab.removeClass(tabHiddenClass).width('');
contentTabsEffect[options.effect].show({tab:tab, fast:true});
} else {
var tabWidth = tab.width();
if(tabWidth) {
tab.width(tabWidth);
}
tab.addClass(tabHiddenClass);
}
// event handler
link.bind(options.event, function(e){
if(link != prevActiveLink && !animating) {
switchTab(prevActiveLink, link);
prevActiveLink = link;
}
});
if(options.attrib === 'href') {
link.bind('click', function(e){
e.preventDefault();
});
}
});
// tab switch function
function switchTab(oldLink, newLink) {
animating = true;
var oldTab = oldLink.data('ctab');
var newTab = newLink.data('ctab');
prevActiveLink = newLink;
currentTab = newTab;
// refresh pagination links
(options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass);
(options.addToParent ? newLink.data('cparent') : newLink).addClass(options.activeClass);
// hide old tab
resizeHolder(oldTab, true);
contentTabsEffect[options.effect].hide({
speed: options.animSpeed,
tab:oldTab,
complete: function() {
// show current tab
resizeHolder(newTab.removeClass(tabHiddenClass).width(''));
contentTabsEffect[options.effect].show({
speed: options.animSpeed,
tab:newTab,
complete: function() {
if(!oldTab.is(newTab)) {
oldTab.width(oldTab.width()).addClass(tabHiddenClass);
}
animating = false;
resizeHolder(newTab, false);
autoRotate();
}
});
}
});
}
// holder auto height
function resizeHolder(block, state) {
var curBlock = block && block.length ? block : currentTab;
if(options.autoHeight && curBlock) {
tabHolder.stop();
if(state === false) {
tabHolder.css({height:''});
} else {
var origStyles = curBlock.attr('style');
curBlock.show().css({width:curBlock.width()});
var tabHeight = curBlock.outerHeight(true);
if(!origStyles) curBlock.removeAttr('style'); else curBlock.attr('style', origStyles);
if(state === true) {
tabHolder.css({height: tabHeight});
} else {
tabHolder.animate({height: tabHeight}, {duration: options.animSpeed});
}
}
}
}
if(options.autoHeight) {
$(window).bind('resize orientationchange', function(){
tabs.not(currentTab).removeClass(tabHiddenClass).show().each(function(){
var tab = jQuery(this), tabWidth = tab.css({width:''}).width();
if(tabWidth) {
tab.width(tabWidth);
}
}).hide().addClass(tabHiddenClass);
resizeHolder(currentTab, false);
});
}
// autorotation handling
var rotationTimer;
function nextTab() {
var activeItem = (options.addToParent ? tabLinksParents : tabLinks).filter('.' + options.activeClass);
var activeIndex = (options.addToParent ? tabLinksParents : tabLinks).index(activeItem);
var newLink = tabLinks.eq(activeIndex < tabLinks.length - 1 ? activeIndex + 1 : 0);
prevActiveLink = tabLinks.eq(activeIndex);
switchTab(prevActiveLink, newLink);
}
function autoRotate() {
if(options.autoRotate && tabLinks.length > 1) {
clearTimeout(rotationTimer);
rotationTimer = setTimeout(function() {
if(!animating) {
nextTab();
} else {
autoRotate();
}
}, options.switchTime);
}
}
autoRotate();
});
};
// add stylesheet for tabs on DOMReady
var tabHiddenClass = 'js-tab-hidden';
$(function() {
var tabStyleSheet = $('<style type="text/css">')[0];
var tabStyleRule = '.'+tabHiddenClass;
tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}';
if (tabStyleSheet.styleSheet) {
tabStyleSheet.styleSheet.cssText = tabStyleRule;
} else {
tabStyleSheet.appendChild(document.createTextNode(tabStyleRule));
}
$('head').append(tabStyleSheet);
});
// tab switch effects
var contentTabsEffect = {
none: {
show: function(o) {
o.tab.css({display:'block'});
if(o.complete) o.complete();
},
hide: function(o) {
o.tab.css({display:'none'});
if(o.complete) o.complete();
}
},
fade: {
show: function(o) {
if(o.fast) o.speed = 1;
o.tab.fadeIn(o.speed);
if(o.complete) setTimeout(o.complete, o.speed);
},
hide: function(o) {
if(o.fast) o.speed = 1;
o.tab.fadeOut(o.speed);
if(o.complete) setTimeout(o.complete, o.speed);
}
},
slide: {
show: function(o) {
var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true);
var tmpWrap = $('<div class="effect-div">').insertBefore(o.tab).append(o.tab);
tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'}); o.tab.css({marginTop:-tabHeight,display:'block'});
if(o.fast) o.speed = 1;
o.tab.animate({marginTop: 0}, {duration: o.speed, complete: function(){
o.tab.css({marginTop: '', width: ''}).insertBefore(tmpWrap);
tmpWrap.remove();
if(o.complete) o.complete();
}});
},
hide: function(o) {
var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true);
var tmpWrap = $('<div class="effect-div">').insertBefore(o.tab).append(o.tab);
tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'});
if(o.fast) o.speed = 1;
o.tab.animate({marginTop: -tabHeight}, {duration: o.speed, complete: function(){
o.tab.css({display:'none', marginTop:'', width:''}).insertBefore(tmpWrap);
tmpWrap.remove();
if(o.complete) o.complete();
}});
}
}
};
}(jQuery));
如果不试图通过解释来弄清楚您的代码,我认为最好默认隐藏所有选项卡面板。
.ui-tabs-panel {
display: none;
/*overflow: hidden;
opacity: 0;*/
}
你的 options.activeClass
应该有:
.ui-tabs-panel.active {
display: block;
overflow-y: auto;
/*transition: opacity 1s ease-in-out;*/
}
这样您就可以通过 .active
class 覆盖可见状态。
但是,如果它是您想要实现的动画,您可能想尝试使用 opacity
。未经测试,我通常在 CSS3 中第一次尝试失败,因此在 jQuery:
中
var tabPanelOptions = options.tabPanelOptions || {
duration: 200,
easing: 'linear'
};
$(options.tabPanel).fadeToggle(tabPanelOptions);
整个想法是 switch/reverse 默认状态的可见性。
通过在 js 脚本的这一行中将 display:block;
的值更改为 display:none;
解决了问题:
tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}';
我正在使用以下代码创建一个选项卡式框。有一个包含很多内容的选项卡,当该选项卡未处于活动状态时,页脚下方会出现一大堆白色 space。本质上,内容在不活动时并没有真正隐藏,这是我需要它做的。我已经包含了基本代码和 js 脚本。
我尝试设置高度和溢出来滚动,但不是很满意。非常感谢任何帮助。
参考框架代码如下:
<div class="product-collateral">
<ul class="tabset">
<li class="active"><a href="#tab1">Tab 1</a></li>
<li><a href="#tab2">Tab 2</a></li>
<li><a href="#tab3">Tab 3</a></li>
<li><a href="#tab4">Tab 4</a></li>
<li><a href="#tab5">Tab 5</a></li>
<li><a href="#tab6">Tab 6</a></li>
<li><a href="#tab7">Tab 7</a></li>
</ul>
<div class="box-collateral tab-content">
<div id="tab1">
</div>
<div id="tab2">
</div>
<div id="tab3">
</div>
<div id="tab4">
</div>
<div id="tab5">
</div>
<div id="tab6">
</div>
<div id="tab7">
</div>
</div><!-- /box-collateral tab-content -->
</div><!-- /product-collateral -->
这是 js 脚本
/*
* jQuery Tabs plugin
*/
;(function($){
$.fn.contentTabs = function(o){
// default options
var options = $.extend({
activeClass:'active',
addToParent:false,
autoHeight:false,
autoRotate:false,
checkHash:false,
animSpeed:400,
switchTime:3000,
effect: 'none', // "fade", "slide"
tabLinks:'a',
attrib:'href',
event:'click'
},o);
return this.each(function(){
var tabset = $(this), tabs = $();
var tabLinks = tabset.find(options.tabLinks);
var tabLinksParents = tabLinks.parent();
var prevActiveLink = tabLinks.eq(0), currentTab, animating;
var tabHolder;
// handle location hash
if(options.checkHash && tabLinks.filter('[' + options.attrib + '="' + location.hash + '"]').length) {
(options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass);
setTimeout(function() {
window.scrollTo(0,0);
},1);
}
// init tabLinks
tabLinks.each(function(){
var link = $(this);
var href = link.attr(options.attrib);
var parent = link.parent();
href = href.substr(href.lastIndexOf('#'));
// get elements
var tab = $(href);
tabs = tabs.add(tab);
link.data('cparent', parent);
link.data('ctab', tab);
// find tab holder
if(!tabHolder && tab.length) {
tabHolder = tab.parent();
}
// show only active tab
var classOwner = options.addToParent ? parent : link;
if(classOwner.hasClass(options.activeClass) || (options.checkHash && location.hash === href)) {
classOwner.addClass(options.activeClass);
prevActiveLink = link; currentTab = tab;
tab.removeClass(tabHiddenClass).width('');
contentTabsEffect[options.effect].show({tab:tab, fast:true});
} else {
var tabWidth = tab.width();
if(tabWidth) {
tab.width(tabWidth);
}
tab.addClass(tabHiddenClass);
}
// event handler
link.bind(options.event, function(e){
if(link != prevActiveLink && !animating) {
switchTab(prevActiveLink, link);
prevActiveLink = link;
}
});
if(options.attrib === 'href') {
link.bind('click', function(e){
e.preventDefault();
});
}
});
// tab switch function
function switchTab(oldLink, newLink) {
animating = true;
var oldTab = oldLink.data('ctab');
var newTab = newLink.data('ctab');
prevActiveLink = newLink;
currentTab = newTab;
// refresh pagination links
(options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass);
(options.addToParent ? newLink.data('cparent') : newLink).addClass(options.activeClass);
// hide old tab
resizeHolder(oldTab, true);
contentTabsEffect[options.effect].hide({
speed: options.animSpeed,
tab:oldTab,
complete: function() {
// show current tab
resizeHolder(newTab.removeClass(tabHiddenClass).width(''));
contentTabsEffect[options.effect].show({
speed: options.animSpeed,
tab:newTab,
complete: function() {
if(!oldTab.is(newTab)) {
oldTab.width(oldTab.width()).addClass(tabHiddenClass);
}
animating = false;
resizeHolder(newTab, false);
autoRotate();
}
});
}
});
}
// holder auto height
function resizeHolder(block, state) {
var curBlock = block && block.length ? block : currentTab;
if(options.autoHeight && curBlock) {
tabHolder.stop();
if(state === false) {
tabHolder.css({height:''});
} else {
var origStyles = curBlock.attr('style');
curBlock.show().css({width:curBlock.width()});
var tabHeight = curBlock.outerHeight(true);
if(!origStyles) curBlock.removeAttr('style'); else curBlock.attr('style', origStyles);
if(state === true) {
tabHolder.css({height: tabHeight});
} else {
tabHolder.animate({height: tabHeight}, {duration: options.animSpeed});
}
}
}
}
if(options.autoHeight) {
$(window).bind('resize orientationchange', function(){
tabs.not(currentTab).removeClass(tabHiddenClass).show().each(function(){
var tab = jQuery(this), tabWidth = tab.css({width:''}).width();
if(tabWidth) {
tab.width(tabWidth);
}
}).hide().addClass(tabHiddenClass);
resizeHolder(currentTab, false);
});
}
// autorotation handling
var rotationTimer;
function nextTab() {
var activeItem = (options.addToParent ? tabLinksParents : tabLinks).filter('.' + options.activeClass);
var activeIndex = (options.addToParent ? tabLinksParents : tabLinks).index(activeItem);
var newLink = tabLinks.eq(activeIndex < tabLinks.length - 1 ? activeIndex + 1 : 0);
prevActiveLink = tabLinks.eq(activeIndex);
switchTab(prevActiveLink, newLink);
}
function autoRotate() {
if(options.autoRotate && tabLinks.length > 1) {
clearTimeout(rotationTimer);
rotationTimer = setTimeout(function() {
if(!animating) {
nextTab();
} else {
autoRotate();
}
}, options.switchTime);
}
}
autoRotate();
});
};
// add stylesheet for tabs on DOMReady
var tabHiddenClass = 'js-tab-hidden';
$(function() {
var tabStyleSheet = $('<style type="text/css">')[0];
var tabStyleRule = '.'+tabHiddenClass;
tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}';
if (tabStyleSheet.styleSheet) {
tabStyleSheet.styleSheet.cssText = tabStyleRule;
} else {
tabStyleSheet.appendChild(document.createTextNode(tabStyleRule));
}
$('head').append(tabStyleSheet);
});
// tab switch effects
var contentTabsEffect = {
none: {
show: function(o) {
o.tab.css({display:'block'});
if(o.complete) o.complete();
},
hide: function(o) {
o.tab.css({display:'none'});
if(o.complete) o.complete();
}
},
fade: {
show: function(o) {
if(o.fast) o.speed = 1;
o.tab.fadeIn(o.speed);
if(o.complete) setTimeout(o.complete, o.speed);
},
hide: function(o) {
if(o.fast) o.speed = 1;
o.tab.fadeOut(o.speed);
if(o.complete) setTimeout(o.complete, o.speed);
}
},
slide: {
show: function(o) {
var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true);
var tmpWrap = $('<div class="effect-div">').insertBefore(o.tab).append(o.tab);
tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'}); o.tab.css({marginTop:-tabHeight,display:'block'});
if(o.fast) o.speed = 1;
o.tab.animate({marginTop: 0}, {duration: o.speed, complete: function(){
o.tab.css({marginTop: '', width: ''}).insertBefore(tmpWrap);
tmpWrap.remove();
if(o.complete) o.complete();
}});
},
hide: function(o) {
var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true);
var tmpWrap = $('<div class="effect-div">').insertBefore(o.tab).append(o.tab);
tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'});
if(o.fast) o.speed = 1;
o.tab.animate({marginTop: -tabHeight}, {duration: o.speed, complete: function(){
o.tab.css({display:'none', marginTop:'', width:''}).insertBefore(tmpWrap);
tmpWrap.remove();
if(o.complete) o.complete();
}});
}
}
};
}(jQuery));
如果不试图通过解释来弄清楚您的代码,我认为最好默认隐藏所有选项卡面板。
.ui-tabs-panel {
display: none;
/*overflow: hidden;
opacity: 0;*/
}
你的 options.activeClass
应该有:
.ui-tabs-panel.active {
display: block;
overflow-y: auto;
/*transition: opacity 1s ease-in-out;*/
}
这样您就可以通过 .active
class 覆盖可见状态。
但是,如果它是您想要实现的动画,您可能想尝试使用 opacity
。未经测试,我通常在 CSS3 中第一次尝试失败,因此在 jQuery:
var tabPanelOptions = options.tabPanelOptions || {
duration: 200,
easing: 'linear'
};
$(options.tabPanel).fadeToggle(tabPanelOptions);
整个想法是 switch/reverse 默认状态的可见性。
通过在 js 脚本的这一行中将 display:block;
的值更改为 display:none;
解决了问题:
tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}';