带有 JQuery 动画的 CSS3 菜单无法正确格式化和显示
CSS3 Menu with JQuery Animation not formating and displaying correctly
我在以下位置为此问题创建了一个jfiddle:JSFiddle显示菜单问题
我正在尝试使用 jquery 和 css3 创建一个很酷的菜单,主要是因为熟悉。我愿意切换到完整的 CSS3,但我不太确定如何做到这一点。 我有几个问题似乎无法解决。代码如下:
JavaScript:
(function ($) {
$.fn.hoverIntent = function (f, g) {
// default configuration options
var cfg = {
sensitivity: 7,
interval: 100,
timeout: 0
};
// override configuration options with user supplied object
cfg = $.extend(cfg, g ? {
over: f,
out: g
} : f);
// instantiate variables
// cX, cY = current X and Y position of mouse, updated by mousemove event
// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
var cX, cY, pX, pY;
// A private function for getting mouse position
var track = function (ev) {
cX = ev.pageX;
cY = ev.pageY;
};
// A private function for comparing current and previous mouse position
var compare = function (ev, ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
// compare mouse positions to see if they've crossed the threshold
if ((Math.abs(pX - cX) + Math.abs(pY - cY)) < cfg.sensitivity) {
$(ob).unbind("mousemove", track);
// set hoverIntent state to true (so mouseOut can be called)
ob.hoverIntent_s = 1;
return cfg.over.apply(ob, [ev]);
} else {
// set previous coordinates for next time
pX = cX;
pY = cY;
// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
ob.hoverIntent_t = setTimeout(function () {
compare(ev, ob);
}, cfg.interval);
}
};
// A private function for delaying the mouseOut function
var delay = function (ev, ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s = 0;
return cfg.out.apply(ob, [ev]);
};
// A private function for handling mouse 'hovering'
var handleHover = function (e) {
// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
while (p && p != this) {
try {
p = p.parentNode;
} catch (e) {
p = this;
}
}
if (p == this) {
return false;
}
// copy objects to be passed into t (required for event object to be passed in IE)
var ev = jQuery.extend({}, e);
var ob = this;
// cancel hoverIntent timer if it exists
if (ob.hoverIntent_t) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
}
// else e.type == "onmouseover"
if (e.type == "mouseover") {
// set "previous" X and Y position based on initial entry point
pX = ev.pageX;
pY = ev.pageY;
// update "current" X and Y position based on mousemove
$(ob).bind("mousemove", track);
// start polling interval (self-calling timeout) to compare mouse coordinates over time
if (ob.hoverIntent_s != 1) {
ob.hoverIntent_t = setTimeout(function () {
compare(ev, ob);
}, cfg.interval);
}
// else e.type == "onmouseout"
} else {
// unbind expensive mousemove event
$(ob).unbind("mousemove", track);
// if hoverIntent state is true, then call the mouseOut function after the specified delay
if (ob.hoverIntent_s == 1) {
ob.hoverIntent_t = setTimeout(function () {
delay(ev, ob);
}, cfg.timeout);
}
}
};
// bind the function to the two event listeners
return this.mouseover(handleHover).mouseout(handleHover);
};
})(jQuery);
$(function () {
var config = {
sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)
interval: 200, // number = milliseconds for onMouseOver polling interval
over: doOpen, // function = onMouseOver callback (REQUIRED)
timeout: 200, // number = milliseconds delay before onMouseOut
out: doClose // function = onMouseOut callback (REQUIRED)
};
function doOpen() {
$(this).addClass("hover");
$('ul:first', this).css('visibility', 'visible');
}
function doClose() {
$(this).removeClass("hover");
$('ul:first', this).css('visibility', 'hidden');
}
$("ul.dropdown li").hoverIntent(config);
$("ul.dropdown li ul li:has(ul)").find("a:first").append(" » ");
$("ul.dropdown li ul li:has(ul)").find("span:first").append(" » ");
});
CSS3:
.main_nav {
background-color:#ffffff;
text-align:center;
float:left;
height:50px;
}
.main_nav ul{
list-style:outside none none !important;
text-align: center;
display: inline;
width: 80%;
}
/*
LEVEL ONE
*/
ul.dropdown { position: relative; white-space: nowrap;text-wrap: none;}
ul.dropdown li { font-weight: bold; float: left; background: #ffffff; color: #4b2c17; }
ul.dropdown a:hover { color: #ffffff; }
ul.dropdown a:active { color: #ffa500; }
ul.dropdown li a { display: block; padding: 4px 8px; border-right: 1px solid #333;
color: #222; }
ul.dropdown li:last-child a { border-right: none; } /* Doesn't work in IE */
ul.dropdown li.hover,
ul.dropdown li:hover { background: rgb(214, 210, 0); color: #ffffff; position: relative; }
ul.dropdown li.hover a { color: black; }
ul.dropdown li:hover h4 {background: #ffffff;color: #4b2c17;}
/*
LEVEL TWO
*/
ul.dropdown ul { visibility: hidden; position: absolute; top: 100%; left: 0; padding-left: 0px !important;}
ul.dropdown ul li { font-weight: normal; background: #ffffff; color: #4b2c17;
border-bottom: 1px solid #222; float: none; }
/* IE 6 & 7 Needs Inline Block */
ul.dropdown ul li a { border-right: none; width: 100%; display: inline-block; }
/*
LEVEL THREE
*/
ul.dropdown ul ul { left: 100%; top: 0; }
ul.dropdown li:hover > ul { visibility: visible; }
/*
LEVEL Four
*/
ul.dropdown ul ul ul { left: 100%; top: 0; }
ul.dropdown ul ul li:hover > ul { visibility: visible; }
和 HTML:
<div class="main_nav">
<ul class="dropdown">
<li><a href="/main">Home</a></li>
<li><a href="/edituser">User</a>
<ul class="sub_menu">
<li class="subnavhead"><h3>New Users</h3></li>
<li><a href="/register">Add New User</a></li>
<li><a href="/validateuser">Validate Users</a></li>
<li class="subnavhead"><h3>Current Users</h3></li>
<li><a href="/edituser">Edit User Information</a></li>
</ul>
</li>
<li class="topnav"><a href="#">Head 2</a>
<ul class="sub_menu">
<li><a target="new" href="#">Subhead 1</a></li>
<li class="subnavhead"><h4><span>Section Group</span></h4>
<ul class="thirdnav">
<li><a href="#">Subgroup head 1</a>
<ul class="thirdnav">
<li><a href="#">Subgroup item 1</a></li>
<li><a href="#">Subgroup item 2</a></li>
</ul>
</li>
<li><a href="#">Subgroup head 2</a>
<ul class="thirdnav">
<li><span>Subgroup item head 1</span>
<ul class="thirdnav">
<li><a href="#">third level 1</a></li>
<li><a href="#">third level 2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
这些代码应该生成一个多级菜单,能够跟踪突出显示的内容;但是,其中有几个异常行为,我目前无法修复。
首先是主导航栏的宽度。 无论我尝试定义的宽度参数如何,我都无法让菜单展开以填充菜单栏,甚至 80%。
第二个是下拉菜单组件上 LI 的宽度。 如您所见,我能够防止行换行,但是如图所示,<li>
不会拉伸最长文本的宽度。 除此之外,你会看到亮点不一致,我不知道为什么。 我尝试了多种变体,但没有成功。
最后一个问题是为什么那个愚蠢的>>出现在 sugroup head 2 下的最后一个 html 链接上。 逻辑不符合这一点,但它似乎出现了。
任何帮助将不胜感激!
谢谢!Jon
如果我正确理解了这些问题,我认为我已经解决了 2 和 3。关于第 1 期我根本不明白你的意思......您希望整个菜单占据整个页面的宽度?如果您能澄清一下,那将非常有帮助。
无论如何,对于第 2 期(再次,如果我理解正确的话),您可以通过禁用包装并将width
设置为 100%
来使菜单占用最长项目的宽度:
ul.dropdown ul li {
font-weight: normal;
background: #ffffff;
color: #4b2c17;
border-bottom: 1px solid #222;
width: 100%;
white-space:nowrap;
}
对于第 3 期,Prachit 说得对。:has
jQuery 选择器与.find
相结合给您带来了麻烦,因为"第三级 1"的a
标签是与您的选择器$("ul.dropdown li ul li:has(ul)").find(" a:first")
匹配的li
的第一个后代a
标签。在这种情况下,您应该只查找与您的选择器匹配的li
的直接子项,因此您的行将变为:
$("ul.dropdown li ul li:has(ul)").find("> a:first").append(" » ");
无论如何,我在这里更新了你的小提琴:http://jsfiddle.net/tzn1x7uq/5/
希望我能帮上忙。
其他答案似乎对问题2和3有很好的解决方案。使用position:absolute
时,儿童的身高和宽度不像平时那样粘附。使用white-space: nowrap
将纠正这一点(尽管使用width:100%
不会有所作为)。
这一行:
$("ul.dropdown li ul li:has(ul)").find("> a:first").append(" » ");
工作正常,除了:has()
之外还有其他方法可以解决这个问题,但它有效。您可以通过从以下规则中删除background
来更正"标题 2">"部分组"的悬停问题:
ul.dropdown li:hover h4 {background: #ffffff;color: #4b2c17;}
最后是无法设置宽度的问题。有几件事需要发生。首先,请确保设置文档的宽度:
html, body{
width: 100%;
}
接下来,您需要将相同添加到所有父项(百分比宽度仅在父项也具有定义的宽度时才有效)。所以从.main_nav
开始:
.main_nav {
width: 100%; //add
background-color:#ffffff;
text-align:center;
height:50px;
}
您遇到问题的最大原因是因为.main_nav ul
被设置为display: inline
。 inline
不会不尊重孩子的宽度/高度,因此打电话width: 100%
不会对它产生影响。更改为inline-block
或仅block
,现在添加宽度:
.main_nav ul{
width: 100%; //add
list-style:outside none none !important;
text-align: center;
display: inline-block; //add
padding: 0; //clear the default padding set on ul elements
}
接下来,您的列表项是浮动的,您需要清除这些项。通常overflow:hidden
是清除浮点数的好方法,但在这种情况下,您的子导航将"溢出"您的内容,因此最好使用 clearfix:
.main_nav ul:after{
content: "";
display: block;
clear: both;
}
现在,您可以在li
上设置大小:
ul.dropdown li { width:33%; font-weight: bold; float: left; background: #ffffff; color: #4b2c17; }
由于您的样式是通过共享定位条件继承的,因此您需要为子导航li
s 使用width: 100%
覆盖之前的33%
宽度:
ul.dropdown ul li { font-weight: normal; background: #ffffff; color: #4b2c17; border-bottom: 1px solid #222; float: none; width: 100%; //add }
现在,您的列表将采用整个宽度。您还有其他问题,例如,使用visibility: hidden
不是一个好主意。虽然该元素被"隐藏"在视线之外,但它仍然占用页面上的空间(如果您向右滚动并且有很多多余的空间,您将看到)。还有一个事实是,你的"head 2"菜单有太多的子导航和向右延伸,以至于把它塞进角落并不理想。您可能需要重新访问其显示方式。也许让它向下下降而不是两个右边。也只是一个UI/UX提示,拥有如此多级别的下拉列表对于用户来说并不受欢迎。但这将取决于你。从结构上讲,这可能需要很多工作,你应该利用类名,这样你就不会让孩子继承不必要的风格,但我希望这能让你走上正确的道路:
小提琴
you can use it.
<style>
body {
padding: 20px 50px 150px;
font-size: 13px;
text-align: center;
/* background: #E3CAA1;*/
}
ul.dr_menu {
text-align: left;
display: inline;
margin: 0;
padding: 15px 4px 17px 0;
list-style: none;
/*-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);*/
}
ul.dr_menu li {
font: bold 12px/18px;
display: inline-block;
margin-right: -4px;
position: relative;
padding: 15px 20px;
/* background: #fff;*/
cursor: pointer;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
ul.dr_menu li:hover {
background: #0b86c8;
color: #fff;
}
ul.dr_menu li ul {
padding: 0;
position: absolute;
top: 48px;
left: 0;
width: 150px;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
display: none;
opacity: 0;
visibility: hidden;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
ul.dr_menu li ul li {
background: #0b86c8;
display: block;
color: #fff;
text-shadow: 0 -1px 0 #000;
}
ul.dr_menu li ul li:hover { background: #666; }
ul.dr_menu li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
</style>
<body>
<ul class="dr_menu">
<li>
Add Management
<ul>
<li>My Add</li>
</ul>
</li>
<li>
API Management
<ul>
<li>Create API</li>
<li>Manage API</li>
<li>Test API</li>
<li>Document API</li>
</ul>
</li>
</ul>
</body>
-
主导航栏的宽度不会扩展,因为
.main_nav
有float: left;
,所以如果你以百分比将宽度添加到li
,它不会扩散。您可以将width
添加到.main_nav
,然后以百分比li
,它将沿.main_nav
宽度分布。 -
在下拉列表中设置
li
width
以获得所需的宽度下拉列表。不确定你的意思是突出显示不一致,如果你的意思是额外的空格,那是因为标题标签h3
和h4
有一些默认的padding
和margin
。将margin
和padding
设置为0
以进行h3
和h4
。 -
显示
>>
是因为您在$("ul.dropdown li ul li:has(ul)").find("a:first").append(" » ");
中使用了has
选择器。 如果 tag 存在于其后代中的任何位置,而不仅仅是作为直接子项,则has
匹配。
你要找的吗? http://jsfiddle.net/tzn1x7uq/7/
1一. 主菜单是100%宽度:width: 100%; /*ADDED LINE*/
1b. 菜单链接占用更多空间:
ul.dropdown li a {
display: block; padding: 4px 30px; border-right: 1px solid #333; color: #222;
} /*ADDED padding 30px*/
防止换行:
ul li {white-space: nowrap;} /*ADDED LINE*/
2b. 奇怪的突出显示内容:
h3{ margin: 0px;}
你也有<h4><span>text here</span></h4>
,我改成了<h3>Text here</h3>
»
引起的随机>>/* COMMENTED OUT: GAVE YOU THE >> things $("ul.dropdown li ul li:has(ul)").find("a:first").append(" » "); $("ul.dropdown li ul li:has(ul)").find("span:first").append(" » "); */
希望这有帮助!
您可以使用仅使用CSS好友来获得悬停效果。
<div id="navigation">
<ul class="menu">
<li><a href="/main">Home</a></li>
<li><a href="/edituser">User</a>
<ul class="sub-menu">
<li>
<h3>New Users</h3>
<a href="/register">Add New User</a>
</li>
<li><a href="/validateuser">Validate Users</a></li>
<li>
<h3>Current Users</h3>
<a href="/edituser">Edit User Information</a>
</li>
</ul>
</li>
<li><a href="/edituser">User 2</a>
<ul class="sub-menu">
<li>
<h3>New Users</h3>
<a href="/register">Add New User</a>
<ul class="sub-menu">
<li>
<h3>New Users 2</h3>
<a href="/register">Add New User</a>
<ul class="sub-menu">
<li>
<h3>New Users 3</h3>
<a href="/register">Add New User</a>
</li>
<li><a href="/validateuser">Validate Users</a></li>
<li>
<h3>Current Users</h3>
<a href="/edituser">Edit User Information</a>
</li>
</ul>
</li>
<li><a href="/validateuser">Validate Users</a></li>
<li>
<h3>Current Users</h3>
<a href="/edituser">Edit User Information</a>
</li>
</ul>
</li>
<li><a href="/validateuser">Validate Users</a></li>
<li>
<h3>Current Users</h3>
<a href="/edituser">Edit User Information</a>
</li>
</ul>
</li>
<li><a href="/edituser">User 3</a>
<ul class="sub-menu">
<li>
<h3>New Users</h3>
<a href="/register">Add New User</a>
</li>
<li><a href="/validateuser">Validate Users</a></li>
<li>
<h3>Current Users</h3>
<a href="/edituser">Edit User Information</a>
</li>
</ul>
</li>
</ul>
对于 CSS
#navigation:before,
#navigation:after { clear: both; content: ' '; display: block; }
#navigation ul { padding: 0; }
#navigation li { float: left; list-style: none; position: relative; }
#navigation li a { display: block; padding: 5px 15px; text-decoration: none; white-space: nowrap; }
#navigation li a:hover { background-color: #222; color: #fff; }
#navigation li ul,
#navigation li:hover ul ul,
#navigation li li:hover ul ul { display: none; position: absolute; }
#navigation li:hover ul,
#navigation li li:hover ul,
#navigation li li li:hover ul { display: block; }
#navigation li li { float: none; }
#navigation ul ul ul { left: 100%; top: 0;}
h3 { margin: 0; }
js 小提琴演示
- 高亮显示包含<br>以及重新格式化网格
- 用逗号分割字符串,格式化后显示
- momentjs 显示本地时间和自动格式化字符串
- Javascript-格式化数字,始终显示原始的小数位数
- jq网格;以 JSON 格式提取的日期未显示在表中.也无法格式化日期
- 如何在页面中显示和格式化 HTML 代码
- 在显示绑定属性之前在 JavaScript 中格式化绑定属性
- 带有 JQuery 动画的 CSS3 菜单无法正确格式化和显示
- 如何格式化干净的数字,使 1000 显示为 1.000,00
- AngularJS:未聚焦时在输入中显示格式化的模型值
- 格式化 JSON 以显示高图表的格式
- 显示格式化的已用时间
- 显示格式无法格式化
- 在HTML中显示未格式化的文本并添加颜色
- 在jQueryUI对话框中显示和格式化数组元素
- 如何水平显示我格式化的JSON数据,类似于电子商务网站
- Ajax源数据表按数据顺序排列,并显示格式化日期
- 仅显示mysql数据库中的格式化文本
- 格式化flexigrid中的单元格以显示值
- tinymce-fontsizeselect格式化显示值