如何显示子菜单的XML子菜单,如果是最后一个节点则显示图像

时间:2017-09-17 19:35:57

标签: javascript jquery html css xml

我正在为学校开展一项任务,我想从XML文件中显示一个菜单。

这是XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<menus>
    <menu text="Subjects">
        <menu text="English">
            <school text="English A" image="E_A.png" />
            <school text="English B" image="E_B.png" />
        </menu>
        <menu text="Maths">
            <school text="Maths A" image="M_A.jpg" />
            <school text="Maths B" image="M_B.jpg" />
        </menu>
    </menu>
    <menu text="Teachers">
        <school text="Sara" image="phones/sara.jpg" />
        <school text="Maya" image="phones/maya.jpg" />
    </menu>
</menus>

我的HTML标记看起来像这样:

<section class="intro">
    <div class="inner">
        <div class="content">
            <h1>Welcome</h1>
        </div>
    </div>
</section>
<footer id="footer">
    <nav id="nav">

    </nav>
</footer>

我使用jQuery和JavaScript从XML文件中读取数据并显示在导航栏中。给出了JavaScript和jQuery代码。

$(document).ready(function() {
    $.ajax({
        type: "GET",
        url: "record.xml",
        dataType: "xml",
        success: function(xml) {
            html = generateMenu(xml);
        }
    });
});

function generateMenu(xml) {
    var mainMenu = $("<ul />");
    $(xml).find('menu').each(function() {
        if ($(this).children().length) {
            var subMenu = $("<ul />");
            $(this).children().each(function() {
                subMenu.append('<li id="' + $(this).attr("text") + '"><a href="#">' + $(this).attr("text") + '</a></li>');
            });
            var li = $('<li id="' + $(this).attr("text") + '"><a href="#">' + $(this).attr("text") + '</a></li>');
            mainMenu.append(li.append(subMenu));
        } else {
            mainMenu.append('<li id="' + $(this).attr("text") + '"><a href="#">' + $(this).attr("text") + '</a></li>');
        }
    });
    $("#nav").append(mainMenu);
}

CSS将帮助您理解正在进行的逻辑。

html, body {
    background-color: #f0efed;
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
    font-family: 'Oswald', sans-serif;
}
.intro {
    height: 90%;
    width: 100%;
    margin: auto;
    top: 0;
    display: table;
}
.intro .inner {
    display: table-cell;
    vertical-align: middle;
    width: 100%;
    max-width: none;
}
.content {
    max-width: 90%;
    margin: 0 auto;
    text-align: center;
    padding: 20px 20px 40px 20px;
}
.content h1 {
    font-family: 'Raleway', sans-serif;
    text-shadow: 0px 0px 300px #000;
    padding-bottom: 10px;
    font-size: 225%;
}
#footer {
    position: fixed;
    bottom: 0;
    margin: 0;
    padding: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 10%;
    font-family: Arial;
    text-shadow: 1px 1px 1px black;
    border-top: 1px solid #dbdbdb;
    background-color: #ffffff;
    box-shadow: inset 0 1px rgba(255,255,255,0.3), inset 0 10px rgba(255,255,255,0.2), inset 0 10px 20px rgba(255,255,255,0.25),inset 0 -15px 30px rgba(255,255,255,0.3);
}

nav {
    width: 100%;
    background: #ffffff;
    padding: 0;
    margin: 0;
    height: 60px;
    position:relative;
}
nav ul {
    background: #ffffff;
    list-style:none;
    padding:0 20px;
    margin: 0;
    height: 60px;

}
nav ul li {
    display: inline-block;
}
nav ul li a {
    color:#333333;
    display:block;
    padding:0px 40px;
    text-decoration:none;
    float: left;
    height: 50px;
    line-height: 50px;
}
nav ul li:hover {
    background: #205791;
    border-radius: 20px;
}
nav ul li:hover > a{
    color:#ffffff;
}

nav ul li:hover > ul {
  display:block;
}
nav ul ul {
    background: #ffffff;
    padding:0;
    display:none;
    width: 100%;
    position: absolute;
    top: -61px;
    left: 0px;
}

显示:然后菜单看起来像那样 enter image description here

In case if you want to see the code in action here is the link to jsfiddle

问题:您可以看到英语和数学显示在父节点中,同时它显示在子节点中。当我鼠标悬停在父节点的Egnlish上时,它显示英语A,英语B.我希望它以正确的顺序。

我还希望触发一个事件,以便在最后一个节点上鼠标悬停的内容div中显示图像。

结构流程将是这样的。 enter image description here 我将感谢你的帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

您使用了find,它忽略了子节点的结构。 此外,您的脚本缺少子菜单级别2的迭代

这是更正的JS代码:

$(document).ready(function() {    
    generateMenu();      
});

function generateMenu(xml) {
    var emptySubMenu = $("<ul />");
    var mainMenu = $("<ul />");

    $('menus').children('menu').each(function() {       
            var li = generateLiNode($(this).attr("text"));

            //get subMenu level 1             
            var subMenuLvl1 = $("<ul />");
            $(this).children().each(function() {
                  var li2 = generateLiNode($(this).attr("text"));

                  //get subMenu level 2  
                  var subMenuLvl2 = $("<ul />");
                  $(this).children().each(function() {
                      subMenuLvl2.append(generateLiNode($(this).attr("text")));                
                  });

                  if (subMenuLvl2.html() != emptySubMenu.html())
                    li2.append(subMenuLvl2);                 
                  //subMenu level 2 is prepared.

                  subMenuLvl1.append(li2);
            });

            if (subMenuLvl1.html() != emptySubMenu.html())
                li.append(subMenuLvl1);
            //subMenu level 1 is prepared.

            mainMenu.append(li);        
    });

    $("#nav").append(mainMenu);
}

function generateLiNode(text)
{
    return $('<li id="' + text + '"><a href="#">' + text + '</a></li>')
}

还有一个有效的JSFiddle: http://jsfiddle.net/c5ghc80s/8/

你的第二个问题可以通过3个步骤解决:

  1. 将第二个参数传递给generateLiNode,方法与传递&#34; text&#34;相同。现在,但这次是&#34;图像&#34;
  2. 打印&#34; id&#34;旁边的图片属性属性
  3. 在文件就绪功能中,在generateMenu()之后,注册onhover事件 您将使用当前li节点的image属性执行任何操作。
  4. 例如,你可以从li元素中取出它并放入img节点的src attribue,它可以放在你的主div中:

    $("li").mouseover(function() {
      $('div > img').attribute("source", $("this").attribute("image"));
    });