Javascript Jquery水平手风琴Webkit错误
我正试图用Jquery构建一个水平的手风琴。在Firefox中,它似乎工作正常。但在Webkit(Safari 3+4和Chrome)中,隐藏功能后,子级别UL闪烁。任何帮助都将不胜感激。要查看正在运行的演示,请执行以下操作: 以下是我正在进行的工作:Javascript Jquery水平手风琴Webkit错误,javascript,jquery,webkit,accordion,Javascript,Jquery,Webkit,Accordion,我正试图用Jquery构建一个水平的手风琴。在Firefox中,它似乎工作正常。但在Webkit(Safari 3+4和Chrome)中,隐藏功能后,子级别UL闪烁。任何帮助都将不胜感激。要查看正在运行的演示,请执行以下操作: 以下是我正在进行的工作: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Typ
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<title>untitled</title>
<style type="text/css">
#container {
display: table;
margin: 0 auto;
text-align: center; /* for IE */
}
ul{
list-style: none;
background-color: yellow;
margin: 0;
padding: 0;
float: left;
height: 20px; /* For testing */
}
ul li {
background-color: aqua;
float: left;
}
ul li ul {
background-color: blue;
display: none;
}
ul li ul li {
background-color: green;
}
a, a:link, a:hover, a:visited, a:active {
color: black;
text-decoration: none;
float: left;
}
</style>
<script type="text/javascript">
/* Care of Hunter Daley */
var $current = null;
$(document).ready(function(){
$("ul li ul").hide(); // hide submenus by default on load
$("ul li a").click(function(){
var $sub = $(this).next();
if ($sub.css("display") == "none")
{
if ($current != null)
$current.animate({ width: 'hide' }); // if you want to only show one sub at a time
$sub.animate({ width: 'show' });
$current = $sub;
}
else
{
$sub.animate({ width: 'hide' });
$current = null;
}
});
});
</script>
</head>
<body>
<div id="container">
<ul>
<li>
<a href="#">Top-level 1</a>
</li>
<li>
<a href="#">Top-level 2</a>
<ul>
<li><a href="#">Bottom Level A1</a></li>
<li><a href="#">Bottom Level A2</a></li>
<li><a href="#">Bottom Level A3</a></li>
<li><a href="#">Bottom Level A4</a></li>
</ul>
</li>
<li>
<a href="#">Top-level 3</a>
<ul>
<li><a href="#">Bottom Level B1</a></li>
<li><a href="#">Bottom Level B2</a></li>
</ul>
</li>
<li>
<a href="#">Top-level 4</a>
</li>
</ul>
</div>
</body>
无标题
#容器{
显示:表格;
保证金:0自动;
文本对齐:居中;/*用于IE*/
}
保险商实验室{
列表样式:无;
背景颜色:黄色;
保证金:0;
填充:0;
浮动:左;
高度:20px;/*用于测试*/
}
ulli{
背景色:浅绿色;
浮动:左;
}
ul li ul{
背景颜色:蓝色;
显示:无;
}
ulli ulli{
背景颜色:绿色;
}
a、 a:链接,a:悬停,a:已访问,a:活动{
颜色:黑色;
文字装饰:无;
浮动:左;
}
/*照顾亨特·戴利*/
var$current=null;
$(文档).ready(函数(){
$(“ul li ul”).hide();//加载时默认隐藏子菜单
$(“ul li a”)。单击(函数(){
var$sub=$(this.next();
如果($sub.css(“显示”)=“无”)
{
如果($current!=null)
$current.animate({width:'hide'});//如果一次只显示一个子对象
$sub.animate({width:'show'});
$current=$sub;
}
其他的
{
$sub.animate({width:'hide'});
$current=null;
}
});
});
-
-
-
-
这听起来好像与我不久前在webkit上遇到的一个问题有关。有一个webkit错误,有时会导致元素的父元素在动画缩小元素的宽度后恢复到其原始大小。动画完成后,元素的父元素跳回其原始大小以适应其内容
编辑:删除关于jQueryUI的评论。不知道为什么我认为你在用它。
讨论了该bug,其中详细介绍了解决方法
我也向jQuery提交了一个
基本上,您需要同时减少$sub
元素父元素的宽度,减少量与减少$sub
的量相同。因此,如果$sub
的宽度为100px,则会有一个单独的animate()
将父对象减少100px
我没有用你的例子测试过这些,但我认为这可能是关键
编辑2:
使用divs的新版本
CSS:
.title {
list-style: none;
margin: 0;
padding: 0;
float: left;
height: 32px; /* For testing */
font-family: helvetica;
font-size: 18px;
clip: auto; overflow: hidden;
}
.menu {
height: 32px; /* For testing */
clip: auto; overflow: hidden;
float: left;
}
a, a:link, a:hover, a:visited, a:active {
color: black;
text-decoration: none;
padding: 12px;
font-weight: 700;
float: left;
color: #222;
}
.menu a, .menu a:link, .menu a:hover, .menu a:visited, .menu a:active {
color: black;
text-decoration: none;
padding: 12px;
font-weight: normal;
float: left;
// Prevents us from having to check for null.
var $current = $('#someFictionalElement');
var $previous = null;
$(document).ready(function(){
$(".menu").css({width: 0}); // hide submenus by default on load
$(".title").click(
function() {
$previous = $current;
$current = $(this);
var $currentMenu = $current.next();
$previous.next().animate({ width: 0 }, {duration: 1000, queue: false} );
// Make sure that if there's no menu text (like Top Level 1 and 4) that it does not animate.
// This is because of the pixels added for Firefox (see comment below)
if( $currentMenu.width() == 0 && $currentMenu.text() != '' ) {
// Expand the menu but keep it hidden so we can get its width
$currentMenu.css({visibility: 'hidden', width: ''});
// Store the width, and add a few pixels for Firefox
var currentWidth = $currentMenu.width() + 3;
// Make menu visible and set with to 0 in preparation for the animation
$currentMenu.css({visibility: 'visible', width: 0})
.animate({ width: currentWidth }, 1000);
}
});
$(".title a").hover(
function(){$(this).animate ({ opacity: 0.7 }, 200);},
function(){$(this).animate ({ opacity: 1 }, 600);}
);
});
<body>
<div id="container">
<div class='title' id='level1'>
<a href="#">Top-level 1</a>
</div>
<div class='menu'></div>
<div class='title' id='level2'>
<a href="#">Top-level 2</a>
</div>
<div class='menu'>
<a href="#">Bottom Level A1</a>
<a href="#">Bottom Level A2</a>
<a href="#">Bottom Level A3</a>
<a href="#">Bottom Level A4</a>
</div>
<div class='title' id='level3'>
<a href="#">Top-level 3</a>
</div>
<div class='menu'>
<a href="#">Bottom Level B1</a>
<a href="#">Bottom Level B2</a>
</div>
<div class='title' id='level4'>
<a href="#">Top-level 4</a>
</div>
<div class='menu'></div>
</div>
</body>
}
javascript:
.title {
list-style: none;
margin: 0;
padding: 0;
float: left;
height: 32px; /* For testing */
font-family: helvetica;
font-size: 18px;
clip: auto; overflow: hidden;
}
.menu {
height: 32px; /* For testing */
clip: auto; overflow: hidden;
float: left;
}
a, a:link, a:hover, a:visited, a:active {
color: black;
text-decoration: none;
padding: 12px;
font-weight: 700;
float: left;
color: #222;
}
.menu a, .menu a:link, .menu a:hover, .menu a:visited, .menu a:active {
color: black;
text-decoration: none;
padding: 12px;
font-weight: normal;
float: left;
// Prevents us from having to check for null.
var $current = $('#someFictionalElement');
var $previous = null;
$(document).ready(function(){
$(".menu").css({width: 0}); // hide submenus by default on load
$(".title").click(
function() {
$previous = $current;
$current = $(this);
var $currentMenu = $current.next();
$previous.next().animate({ width: 0 }, {duration: 1000, queue: false} );
// Make sure that if there's no menu text (like Top Level 1 and 4) that it does not animate.
// This is because of the pixels added for Firefox (see comment below)
if( $currentMenu.width() == 0 && $currentMenu.text() != '' ) {
// Expand the menu but keep it hidden so we can get its width
$currentMenu.css({visibility: 'hidden', width: ''});
// Store the width, and add a few pixels for Firefox
var currentWidth = $currentMenu.width() + 3;
// Make menu visible and set with to 0 in preparation for the animation
$currentMenu.css({visibility: 'visible', width: 0})
.animate({ width: currentWidth }, 1000);
}
});
$(".title a").hover(
function(){$(this).animate ({ opacity: 0.7 }, 200);},
function(){$(this).animate ({ opacity: 1 }, 600);}
);
});
<body>
<div id="container">
<div class='title' id='level1'>
<a href="#">Top-level 1</a>
</div>
<div class='menu'></div>
<div class='title' id='level2'>
<a href="#">Top-level 2</a>
</div>
<div class='menu'>
<a href="#">Bottom Level A1</a>
<a href="#">Bottom Level A2</a>
<a href="#">Bottom Level A3</a>
<a href="#">Bottom Level A4</a>
</div>
<div class='title' id='level3'>
<a href="#">Top-level 3</a>
</div>
<div class='menu'>
<a href="#">Bottom Level B1</a>
<a href="#">Bottom Level B2</a>
</div>
<div class='title' id='level4'>
<a href="#">Top-level 4</a>
</div>
<div class='menu'></div>
</div>
</body>
HTML:
.title {
list-style: none;
margin: 0;
padding: 0;
float: left;
height: 32px; /* For testing */
font-family: helvetica;
font-size: 18px;
clip: auto; overflow: hidden;
}
.menu {
height: 32px; /* For testing */
clip: auto; overflow: hidden;
float: left;
}
a, a:link, a:hover, a:visited, a:active {
color: black;
text-decoration: none;
padding: 12px;
font-weight: 700;
float: left;
color: #222;
}
.menu a, .menu a:link, .menu a:hover, .menu a:visited, .menu a:active {
color: black;
text-decoration: none;
padding: 12px;
font-weight: normal;
float: left;
// Prevents us from having to check for null.
var $current = $('#someFictionalElement');
var $previous = null;
$(document).ready(function(){
$(".menu").css({width: 0}); // hide submenus by default on load
$(".title").click(
function() {
$previous = $current;
$current = $(this);
var $currentMenu = $current.next();
$previous.next().animate({ width: 0 }, {duration: 1000, queue: false} );
// Make sure that if there's no menu text (like Top Level 1 and 4) that it does not animate.
// This is because of the pixels added for Firefox (see comment below)
if( $currentMenu.width() == 0 && $currentMenu.text() != '' ) {
// Expand the menu but keep it hidden so we can get its width
$currentMenu.css({visibility: 'hidden', width: ''});
// Store the width, and add a few pixels for Firefox
var currentWidth = $currentMenu.width() + 3;
// Make menu visible and set with to 0 in preparation for the animation
$currentMenu.css({visibility: 'visible', width: 0})
.animate({ width: currentWidth }, 1000);
}
});
$(".title a").hover(
function(){$(this).animate ({ opacity: 0.7 }, 200);},
function(){$(this).animate ({ opacity: 1 }, 600);}
);
});
<body>
<div id="container">
<div class='title' id='level1'>
<a href="#">Top-level 1</a>
</div>
<div class='menu'></div>
<div class='title' id='level2'>
<a href="#">Top-level 2</a>
</div>
<div class='menu'>
<a href="#">Bottom Level A1</a>
<a href="#">Bottom Level A2</a>
<a href="#">Bottom Level A3</a>
<a href="#">Bottom Level A4</a>
</div>
<div class='title' id='level3'>
<a href="#">Top-level 3</a>
</div>
<div class='menu'>
<a href="#">Bottom Level B1</a>
<a href="#">Bottom Level B2</a>
</div>
<div class='title' id='level4'>
<a href="#">Top-level 4</a>
</div>
<div class='menu'></div>
</div>
</body>
我将此作为一个单独的答案发布,以防您发现前一个答案仍然有用 请注意以下事项:
- 我没有在ie中测试过这个
- 这可以追溯到“嵌套”版本,所以我稍微更改了类和变量名
- 当没有菜单可显示时,不再需要空菜单
- 每个菜单的“容器”的宽度现在减少到与菜单相同的程度。这就消除了webkit的临时闪存(这是最初的策略)
- 您会注意到,菜单的动画计时与菜单容器的动画计时略有不同。基本上,您希望容器在展开时稍微超前,而菜单在缩小时稍微超前。如果定时设置为相等,则菜单会闪烁一些
- 如注释中所述,在开始时,每个菜单通过设置一个以前不存在的名为“fullWidth”的属性,在完全展开时“记忆”其宽度。然后在需要时检索该属性的值。您可以同样轻松地使用全局变量或jQuery的data()函数来存储信息。关键是,如果每个菜单都知道在扩展时应该有多宽,事情就会简化
#container {
margin: 0 auto 0 auto;
text-align: center;
display: table;
}
.menuContainer {
margin: 0;
padding: 0;
float: left;
height: 32px; /* For testing */
font-family: helvetica;
font-size: 18px;
clip: auto; overflow: hidden;
}
.menu {
height: 32px; /* For testing */
clip: auto; overflow: hidden;
float: left;
}
a, a:link, a:hover, a:visited, a:active {
color: black;
text-decoration: none;
padding: 12px;
font-weight: 700;
float: left;
color: #222;
}
.menu a, .menu a:link, .menu a:hover, .menu a:visited, .menu a:active {
color: black;
text-decoration: none;
padding: 12px;
font-weight: normal;
float: left;
}
javascript
var $currentMenuContainer = $('#someFictionalElement');
var $previousMenuContainer = null;
$(document).ready(function() {
// Iterate through each .menu element, setting the full width of each menu to a 'custom'
// attribute called 'fullWidth'. Since the full width should never change, this
// makes it easy to recall it quickly. You could use global variables instead.
// After setting 'fullWidth', it then collapses each menu and title.
$(".menu").each(function() {
var $theMenu = $(this);
var $theMenuContainer = $theMenu.parent();
$theMenu.attr({fullWidth: ($theMenu.width() + 3)}); // Add a few pixels for firefox
var menuContainerWidth = $theMenuContainer.width() - $theMenu.attr('fullWidth') + 6; // Add DOUBLE the pixels here
$theMenu.css({width: 0});
$theMenuContainer.css({width: menuContainerWidth});
});
$(".menuContainer a").click(
function() {
// Set the current and previous elements properly
$previousMenuContainer = $currentMenuContainer;
$currentMenuContainer = $(this).parent();
var $previousMenu = $previousMenuContainer.find('.menu');
var $currentMenu = $currentMenuContainer.find('.menu');
// Collapse the previous menu
$previousMenu.animate({ width: 0 }, {duration: 480, queue: false} );
// Subtract the width of the previous menuContainer's menu from the menuContainer (only if its menu is displayed)
if($previousMenu.width() > 0) $previousMenuContainer.animate({width: ('-=' + $previousMenu.attr('fullWidth'))}, 500);
// Expand the current menu and its menuContainer if it's not showing
if($currentMenu.width() == 0) {
// Increase the menuContainer width by the full width of its menu
$currentMenuContainer.animate({width: ('+=' + $currentMenu.attr('fullWidth'))}, 480);
// Increase the menuContainer to its full width
$currentMenu.animate({ width: $currentMenu.attr('fullWidth') }, 500);
}
});
$(".menuContainer a").hover(
function(){$(this).animate ({ opacity: 0.7 }, 200);},
function(){$(this).animate ({ opacity: 1 }, 600);}
);
});
HTML
<div id="container">
<div class='menuContainer'>
<a href="#">Top-level 1</a>
</div>
<div class='menuContainer'>
<a href="#">Top-level 2</a>
<div class='menu'>
<a href="#">Bottom Level A1</a>
<a href="#">Bottom Level A2</a>
<a href="#">Bottom Level A3</a>
<a href="#">Bottom Level A4</a>
</div>
</div>
<div class='menuContainer'>
<a href="#">Top-level 3</a>
<div class='menu'>
<a href="#">Bottom Level B1</a>
<a href="#">Bottom Level B2</a>
</div>
</div>
<div class='menuContainer'>
<a href="#">Top-level 4</a>
</div>
</div>
编辑:将以下DTD添加到页面顶部-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
我已经试过了,但是当我从Toplevel 4升级到扩展的Toplevel 3时,它仍然闪烁。我会试着弄清楚并重新发布。。。但目前我想不出解决办法。可能:$sub.parent().css({width:''})$当前=$sub?“列表”的使用有多重要