简体   繁体   中英

How to make a hide and show navigation using jQuery/JavaScript?

I wanna make a three-level navigation on my navigation bar, with an array of always displaying starting levels, and two levels show or hide corresponding to the hovering of their parent elements.

I get a little confused since, you must hide the child level element when you move the mouse out of the element, but if you at the same time move to the children elements, you must show the elements which has already been hidden. This is weird, but I've tried a simple solution and it works fine for the 1st level. My solution was like this:

$(parent).mouseover (function() {
    $(children).show();
});

$(parent).mouseout (function() {
    $(children).hide();
});

$(child).mouseover (function() {
    $(this).show();
});

$(child).mouseout (function() {
    $(this).hide();
});

It works fine for the 1st level but doesn't work for the 2nd level. For example, the navigation hierachy looks like this:

- Fruit
    - Apple
        - Fuji
        - Huangjin
    - Pine
    ...
- Juice
...

When I move to the Fruit, all the fruits has been shown, and when I move to Apple, all fruits are still shown and the all kinds of apple are shown, but when I move to a specific kind like Fuji, all Fruits and the kinds are hidden.

I don't why.

By the way how to implement such a hide and show navigation bar? It seems that my "solution" hides and shows the children elements when I move to a child item, but it's weird. Are there any better solutions?

I think it may touch some deep issues about browser event.

The html:

<%@ page language="java" import="java.util.*, cn.xxxx.customer.center.util.*" pageEncoding="utf-8"%>
<%
//不允许浏览器端或缓存服务器缓存当前页面信息。
response.setHeader( "Pragma", "no-cache" );   
response.setDateHeader("Expires", 0);   
response.addHeader( "Cache-Control", "no-cache" );//浏览器和缓存服务器都不应该缓存页面信息
response.addHeader( "Cache-Control", "no-store" );//请求和响应的信息都不应该被存储在对方的磁盘系统中;    
response.addHeader( "Cache-Control", "must-revalidate" );//于客户机的每次请求,代理服务器必须想服务器验证缓存是否过时;

String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
String docName = request.getParameter("name");
String docHtmlPath = Constants.docHtmlBase + docName + ".html";
String docStylePath = Constants.docHtmlBase + docName + ".style";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%= basePath %>">

    <title><%= docName %></title>

    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1, keyword2, keyword3">
    <meta http-equiv="description" content="This is my page">

    <link rel="stylesheet" type="text/css" href="style.css">
    <jsp:include page="<%= docStylePath %>" flush="true" />

    <script type="text/javascript" src="jquery-1.10.2.min.js"></script>
    <!-- <script type="text/javascript" src="jquery-1.10.2.js"></script>  -->
    <script type="text/javascript" src="action.js"></script>

  </head>

  <body>
    <!-- absolute positioned category&item divs -->
    <div id="cate-div1" class="cate-wrapper" nav_div_id="nav-div1">
      <div id="cate-item-div1-1" class="cate-item" doc_div_id="doc-div1-1">A</div>
      <div id="cate-item-div1-2" class="cate-item" doc_div_id="doc-div1-2">B</div>
      <div id="cate-item-div1-3" class="cate-item">C</div>
      <div id="cate-item-div1-4" class="cate-item">D</div>
      <div id="cate-item-div1-5" class="cate-item">E</div>
      <div id="cate-item-div1-6" class="cate-item">F</div>
    </div>
    <div id="cate-div2" class="cate-wrapper" nav_div_id="nav-div2">
      <div id="cate-item-div2-1" class="cate-item">飞机</div>
      <div id="cate-item-div2-2" class="cate-item">导弹</div>
      <div id="cate-item-div2-3" class="cate-item">舰船</div>
    </div>

    <div id="doc-div1-1" class="doc-wrapper" cat_item_div_id="cate-item-div1-1">
    </div>
    <div id="doc-div1-2" class="doc-wrapper" cat_item_div_id="cate-item-div1-2">
    </div>

    <!-- header -->
    <div id="upper-wrapper">
       <div id="header-wrapper">
         <img id="logo-img" src="files/logo.png" />
         <div id="header-text">资料库 </div>
         <div id="nav-wrapper">
           <img class="nav-bar" src="files/nav-bar.png" />
           <a id="nav-div1" class="dropdown-nav-item" cate_div_id="cate-div1">项目</a>
           <img class="nav-bar" src="files/nav-bar.png" />
           <a id="nav-div2" class="dropdown-nav-item" cate_div_id="cate-div2">武器</a>
           <img class="nav-bar" src="files/nav-bar.png" />
         </div>
       </div>
    </div>

    <!-- main content -->
    <div id="main-wrapper">
      <div id="content-wrapper">
        <jsp:include page="<%= docHtmlPath %>" flush="true" />
      </div>
    </div>
  </body>
</html>

the js:

jQuery.extend ({
    initPage: function () {
        $("#header-wrapper").width($("#content-wrapper").innerWidth());
    },

    calcCateDivHeight: function (divs) {
        var h = 0;
        for (var i = 0; i < divs.length; i ++) {
            $(divs[i]).attr("accumHeight", h);
            $(divs[i]).attr("seq", i);
            h += divs[i].height;
        }
    }
});

$(document).ready (function () {
    $.initPage();

    $.calcCateDivHeight($("div#cate-div1 .cate-item"));
    $.calcCateDivHeight($("div#cate-div2 .cate-item"));

    $(window).resize (function () {
        $.initPage();
    });

    $(".dropdown-nav-item").mouseover (function () {
        // update the nav item background
        $(this).css("background-color", "#2a2a2a");

        // display the corresponding category div
        var pos = $(this).offset();
        pos.top += $(this).outerHeight();
        var cate_div = $("#" + $(this).attr("cate_div_id"));
        cate_div.css("left", pos.left);
        cate_div.css("top", pos.top);
        cate_div.attr("leftPos", pos.left);
        cate_div.attr("topPos", pos.top);
        cate_div.show("slow");
    });

    $(".dropdown-nav-item").mouseout (function () {
        // update the nav item background
        $(this).css("background-color", "inherit");

        // hide the corresponding category div
        var cate_div = $("#" + $(this).attr("cate_div_id"));
        cate_div.hide();
    });

    $(".cate-wrapper").mouseover (function () {
        $(this).show();

        // update the nav item background
        var nav_div = $("#" + $(this).attr("nav_div_id"));
        $(nav_div).css("background-color", "#2a2a2a");
    });

    $(".cate-wrapper").mouseout (function () {
        $(this).hide();

        // update the nav item background
        var nav_div = $("#" + $(this).attr("nav_div_id"));
        $(nav_div).css("background-color", "inherit");
    });

    $(".cate-item").mouseover (function () {
        // update the cate item background
        $(this).css("background-color", "#080808");

        var left = Number($(this).parent().attr("leftPos"));
        left += $(this).parent().outerWidth();
        var top = Number($(this).parent().attr("topPos"));
        //top += $(this)[0].accumHeight;
        top += 37 * $(this).attr("seq");
        var doc_div = $("#" + $(this).attr("doc_div_id"));
        doc_div.css("left", left);
        doc_div.css("top", top);
        doc_div.show();
    });

    $(".cate-item").mouseout (function () {
        // update the cate item background
        $(this).css("background-color", "inherit");

        // hide the corresponding doc div
        var doc_div = $("#" + $(this).attr("doc_div_id"));
        doc_div.hide();
    });

    $(".doc-wrapper").mouseover (function () {
        $(this).show();

        // update the nav item background
        var cat_item_div = $("#" + $(this).attr("cat_item_div_id"));
        $(cat_item_div).css("background-color", "#080808");

        // display the corresponding cat div
        $(cat_item_div).parent().show();

        // update the nav item background
        var nav_div = $("#" + $(cat_item_div).parent().attr("nav_div_id"));
        $(nav_div).css("background-color", "#2a2a2a");
    });

    $(".doc-wrapper").mouseout (function () {
        $(this).hide();

        // update the nav item background
        var cat_item_div = $("#" + $(this).attr("cat_item_div_id"));
        $(cat_item_div).css("background-color", "inherit");

        // hide the corresponding cat div
        $(cat_item_div).parent().hide();

        // update the nav item background
        var nav_div = $("#" + $(cat_item_div).parent().attr("nav_div_id"));
        $(nav_div).css("background-color", "inherit");
    });
});

Solved

The problem occurs not in the .html or .js file, but the .css file. I set a 1px border on the wrapper and that separate the mouse moving out and in. It's a little complicated but one thing is important, that in the Javascript/jQuery, when mouse move from a element to another, as long as they're STRICTLY beneath (not even 1px afar), the movein and moveout event will all be executed.

fiddle: http://jsfiddle.net/neuroflux/ssSnN/1/

css:

.child {
    display: none;
}

HTML:

<div id="fruits">
    <div class="roll" id="apple">APPLE
        <div class="child">Fuji</div>
        <div class="child">Huangjin</div>
        <div class="child">Stuff</div>
    </div>

    <div class="roll" id="pine">PINE
        <div class="child">Stuff</div>
        <div class="child">Stuff</div>
        <div class="child">Stuff</div>
    </div>

Javascript:

$('.roll').on('mouseover', function() {
    $('.child').hide();
    $(this).children('.child').show();
}).on('mouseout', function() {
    $('.child').hide();
})

You can use this

$(child).mouseover (function() {
    $(this).find("li").show();
});

if it is ul li.

or

$(child).mouseover (function() {
    $(this).children("li").show();
});

You can do like this:

Html:

<div id="fruits">
    <div class="roll" id="apple">APPLE
        <div class="child">Fuji
             <div class="child2">abc</div>
             <div class="child2">def</div>
        </div>
        <div class="child">Huangjin</div>
        <div class="child">Stuff
             <div class="child2">abc</div>
             <div class="child2">def</div>
        </div>
    </div>

    <div class="roll" id="pine">PINE
        <div class="child">Stuff</div>
        <div class="child">Stuff</div>
        <div class="child">Stuff</div>
    </div>

    <div class="roll" id="juice">JUICE
        <div class="child">Stuff2</div>
        <div class="child">Stuff2</div>
        <div class="child">Stuff2</div>
    </div>
</div>

Css :

.child {
    display: none;
}

* { padding: 6px; }

Javascript:

$(".roll").mouseover(function() {
    $('.child').hide();
    $(this).children('.child').show();
}).on('mouseout', function() {
    $('.child').hide();
})

$(".child").mouseover(function() {
    $('.child').hide();
    $(this).children('.child2').show();
}).on('mouseout', function() {
    $('.child2').hide();
})

Try it..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM