CSS3 带有 JQuery 动画的菜单未正确格式化和显示

CSS3 Menu with JQuery Animation not formating and displaying correctly

我已经为这个问题创建了一个 jfiddle:JSFiddle showing menu problems

我正在尝试使用 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(" &raquo; ");
    $("ul.dropdown li ul li:has(ul)").find("span:first").append(" &raquo; ");

});

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 link 上。逻辑不符合那个,但它似乎出现了。

如有任何帮助,我们将不胜感激!

谢谢! 乔恩

 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>
  1. 主导航栏的宽度不会扩展,因为 .main_navfloat: left;,所以如果您将宽度添加到 li,它不会扩展.您可以将 width 添加到 .main_nav 然后再添加到 li 百分比,它将沿着 .main_nav.

  2. 的宽度展开
  3. 在 drop-down 上设置 liwidth 以获得所需的宽度 drop-down。不确定你所说的突出显示不一致是什么意思,如果你指的是额外的 white-spaces,那是因为标题标签 h3h4 有一些默认的 paddingmargin .对于 h3h4,将 marginpadding 设置为 0

  4. >> 出现是因为您在 $("ul.dropdown li ul li:has(ul)").find("a:first").append(" &raquo; "); 中使用了 has 选择器。 has 如果标签存在于其后代中的任何位置,则匹配,而不仅仅是直接 child.

如果我理解正确的话,我想我已经解决了问题 2 和问题 3。关于问题 1 我根本不明白你的意思...你想让整个菜单占据整个页面的宽度吗?如果您能澄清一下,那将非常有帮助。

无论如何,对于第 2 个问题(同样,如果我理解正确的话),您可以通过禁用换行并将 width 设置为 [=13= 来使菜单占据最长项目的宽度]:

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 的组合给你带来了麻烦,因为 "third level 1" 的 a 标签是第一个后代 a 标签li 与您的选择器 $("ul.dropdown li ul li:has(ul)").find(" a:first") 匹配。在这种情况下,您应该只查找与您的选择器匹配的 li 的直接子代,因此您的行将变成:

$("ul.dropdown li ul li:has(ul)").find("> a:first").append(" &raquo; ");

无论如何,我已经在此处更新了您的 fiddle:http://jsfiddle.net/tzn1x7uq/5/

希望我能帮到你。

这是你要找的吗? http://jsfiddle.net/tzn1x7uq/7/

1a。主菜单为 100% 宽度:width: 100%; /*ADDED LINE*/

1b。菜单链接占用较多space:

ul.dropdown li a { 
    display: block; padding: 4px 30px; border-right: 1px solid #333; color: #222; 
}  /*ADDED padding 30px*/
  1. 防止换行:

    ul li {white-space: nowrap;} /*ADDED LINE*/
    

2b。奇怪的突出显示内容:

h3{ margin: 0px;}

你也有一个<h4><span>text here</span></h4>,我改成了<h3>Text here</h3>

  1. 随机>>由&raquo;

    引起
    /* COMMENTED OUT: GAVE YOU THE >> things
    $("ul.dropdown li ul li:has(ul)").find("a:first").append(" &raquo; ");
    $("ul.dropdown li ul li:has(ul)").find("span:first").append(" &raquo;    ");
    */
    

希望这对您有所帮助!

其他答案似乎对问题 2 和问题 3 有很好的解决方案。使用 position:absolute 时,children 的高度和宽度不会像往常一样粘附。使用 white-space: nowrap 将纠正这一点(尽管使用 width:100% 不会有什么不同)。

这一行:

$("ul.dropdown li ul li:has(ul)").find("> a:first").append(" &raquo; ");

工作正常,除了 :has() 之外,还有其他方法可以解决这个问题,但它确实有效。您可以通过从以下规则中删除 background 来更正“head 2”>“section group”的悬停问题:

ul.dropdown li:hover h4 {background: #ffffff;color: #4b2c17;}

最后是无法设置宽度的问题。有几件事需要发生。首先一定要在文档上设置宽度:

html, body{
   width: 100%;
}

接下来您需要将相同的内容添加到所有 parent(百分比宽度仅在 parent 也具有定义的宽度时才有效)。所以从 .main_nav:

开始
.main_nav {
   width: 100%; //add
   background-color:#ffffff;
   text-align:center;
   height:50px;
}

您遇到问题的最大原因之一是 .main_nav ul 被设置为 display: inlineinline 不尊重它的 children 的 width/height 因此调用 width: 100% 不会对其产生任何影响。更改为 inline-blockblock,然后添加宽度:

.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; }

由于您的样式是通过共享定位继承的,因此您需要为您的子导航 lis:

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 不是一个好主意。虽然该元素“隐藏”在视线之外,但它仍会占用页面上的空间(如果向右滚动就会看到,并且有很多多余的空间 space)。还有一个事实是,您的“head 2”菜单有很多子导航,并且一直向右延伸,因此塞在角落里并不理想。您可能想重新访问它的显示方式。也许让它只是向下下降而不是向右下降两个。也只是一个 UI/UX 提示,用户不太喜欢有这么多级别的下拉菜单。但这将取决于你。从结构上讲,这可能需要做很多工作,您应该利用 class 名称,这样您就不会 children 继承不必要的样式,但我希望这能让您走上正确的道路:

FIDDLE

你可以使用 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 fiddle DEMO