如何干掉这个脚本?

时间:2015-05-14 22:00:37

标签: jquery css navigation dry

我一直在偷看这个导航代码,我终于让我的菜单的第一层工作了。好极了!但是我注意到我的代码只适用于第一层。好吧,有点儿。单击其他菜单时,打开菜单应该关闭。它适用于我的顶级导航选项,但不适用于我的子菜单选项。我很想复制/粘贴代码,以便一切适用于所有级别,但我知道编码中的一个重要规则是不要重复自己(DRY)。那么有人可以看看这个,看看我是否可以将第一个If / Else语句的规则应用到我的所有子菜单中? (子菜单,下拉菜单,幻灯片菜单)。

此外,如果我的顶级导航开始换行,当您单击第二行上的其中一个链接时,子菜单将显示在顶级链接上,使其几乎无法关闭。有办法解决这个问题吗?

这是我的jsFiddle

的jQuery

$(document).ready(function(){ 

$(".nav-tabs span").click(function(){



            var activeTab = $(".nav-tabs > li span.open");
            var submenu = $(this).siblings("ul");
            var thisParent = $(this).closest("ul");

            if (thisParent.hasClass("nav-tabs")){

                if (!$(this).is(activeTab)){
                    /*
                    alert("this link was not active yet");
                    */
                    activeTab.siblings("ul").slideUp(); 
                    submenu.find("span+ul").hide();
                    activeTab.removeClass("open");
                    $(this).addClass("open");
                    submenu.slideDown();

                } else {
                    /*
                    alert("this link is already active");
                    */
                    submenu.slideUp();
                    submenu.find("span+ul").hide();
                    $(this).removeClass("open");
                }
            } else {
                $(this).toggleClass("open");
                submenu.slideToggle("fast", function(){
                    if (!$(this).is(".open")){
                        submenu.find("span+ul").removeClass("open").hide();
                    }
                });

            }


        });

        });

HTML

<div id="navbar">
    <ul class="nav-tabs">
        <li><span>Home</span></li>
        <li id="active"><span>Dogs <div class="arrow-down"></div></span>
            <ul class="sub-menu">
                <li><span>Meet the Breeds<div class="arrow-down"></div></span>
                    <ul class="drop-menu">
                        <li><span>Sort A - Z ~ </span>
                            <ul class="slide-menu">
                                <li>Breeds A - F</li>
                                <li>Breeds G - L</li>
                                <li>Breeds M - R</li>
                                <li>Breeds S - Z</li>
                            </ul>
                        </li>
                        <li><span>Sort by AKC Group ~</span>
                            <ul class="slide-menu">
                                <li>Sporting Group</li>
                                <li>Working Group</li>
                                <li>Herding Group</li>
                                <li>Hound Group</li>
                                <li>Terrier Group</li>
                                <li>Non-Sporting Group</li>
                                <li>Toy Group</li>
                            </ul>
                        </li>
                        <li><span>Sort by Size ~</span>
                            <ul class="slide-menu">
                                <li>X-Small (&le 10in)</li>
                                <li>Small (10in &gt &lt 15in)</li>
                                <li>Medium (15in &ge &lt 21in)</li>
                                <li>Large (21in &ge &lt 28in)</li>
                                <li>X-Large (28in +)</li>
                            </ul>
                        </li>
                        <li><span>Sort by Coat ~</span>
                            <ul class="slide-menu">
                                <li>Very Short/Hairless</li>
                                <li>Short Coat</li>
                                <li>Medium Coats</li>
                                <li>Long Coats</li>
                                <li>Non-Shedding Coats</li>
                                <li>Curly Coats</li>
                            </ul>
                        </li>
                        <li><span>Sort by Trait ~</span>
                            <ul class="slide-menu">
                                <li>Apartment Suitable</li>
                                <li>Laid Back</li>
                                <li>Athletic</li>
                                <li>Protective</li>
                                <li>Extroverted</li>
                                <li>Pet Friendly</li>
                                <li>Cuddle-Buddies</li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li><span>Supplies<div class="arrow-down"></div></span>
                    <ul class="drop-menu">
                        <li><span>Crates & Kennels</li>
                        <li><span>Bowls & Dishes</li>
                        <li><span>Collars & Leashes</li>
                        <li><span>Toys & Games</li>
                        <li><span>Grooming</li>
                        <li><span>Apparal & Accessories</li>
                    </ul>
                </li>
                <li><span>Finding a Dog<div class="arrow-down"></div></span></li>
            </ul>

        </li>
        <li><span>Cats<div class="arrow-down"></div></span>
            <ul class="sub-menu">
                <li><span>Cat Links<div class="arrow-down"></div></span></li>
                <li><span>Cat Links<div class="arrow-down"></div></span></li>
                <li><span>Cat Links<div class="arrow-down"></div></span></li>
                <li><span>Cat Links<div class="arrow-down"></div></span></li>
                <li><span>Cat Links<div class="arrow-down"></div></span></li>
                <li><span>Cat Links<div class="arrow-down"></div></span></li>
            </ul>
        </li>
        <li><span>Birds<div class="arrow-down"></div></span>
            <ul class="sub-menu">
                <li><span>Bird Links<div class="arrow-down"></div></span></li>
                <li><span>Bird Links<div class="arrow-down"></div></span></li>
                <li><span>Bird Links<div class="arrow-down"></div></span></li>
                <li><span>Bird Links<div class="arrow-down"></div></span></li>
                <li><span>Bird Links<div class="arrow-down"></div></span></li>
                <li><span>Bird Links<div class="arrow-down"></div></span></li>
            </ul>
        </li>
        <li><span>Small Mammals<div class="arrow-down"></div></span>
            <ul class="sub-menu">
                <li><span>Sm.Mammal Links<div class="arrow-down"></div></span></li>
                <li><span>Sm.Mammal Links<div class="arrow-down"></div></span></li>
                <li><span>Sm.Mammal Links<div class="arrow-down"></div></span></li>
                <li><span>Sm.Mammal Links<div class="arrow-down"></div></span></li>
                <li><span>Sm.Mammal Links<div class="arrow-down"></div></span></li>
                <li><span>Sm.Mammal Links<div class="arrow-down"></div></span></li>
            </ul>
        </li>
        <li><span>Articles<div class="arrow-down"></div></span>
            <ul class="sub-menu">
                <li><span>Article Links<div class="arrow-down"></div></span></li>
                <li><span>Article Links<div class="arrow-down"></div></span></li>
                <li><span>Article Links<div class="arrow-down"></div></span></li>
                <li><span>Article Links<div class="arrow-down"></div></span></li>
                <li><span>Article Links<div class="arrow-down"></div></span></li>
                <li><span>Article Links<div class="arrow-down"></div></span></li>
            </ul>
        </li>
        <li><span>Videos<div class="arrow-down"></div></span>
            <ul class="sub-menu">
                <li><span>Video Links<div class="arrow-down"></div></span></li>
                <li><span>Video Links<div class="arrow-down"></div></span></li>
                <li><span>Video Links<div class="arrow-down"></div></span></li>
                <li><span>Video Links<div class="arrow-down"></div></span></li>
                <li><span>Video Links<div class="arrow-down"></div></span></li>
                <li><span>Video Links<div class="arrow-down"></div></span></li>
            </ul>
        </li>
        <li><span>Updates<div class="arrow-down"></div></span>
            <ul class="sub-menu">
                <li><span>More Links<div class="arrow-down"></div></span></li>
                <li><span>More Links<div class="arrow-down"></div></span></li>
                <li><span>More Links<div class="arrow-down"></div></span></li>
                <li><span>More Links<div class="arrow-down"></div></span></li>
                <li><span>More Links<div class="arrow-down"></div></span></li>
                <li><span>More Links<div class="arrow-down"></div></span></li>
            </ul>
        </li>
    </ul>
</div>
jsFiddle

中包含

CSS

2 个答案:

答案 0 :(得分:3)

哈!我能够自己找到答案!

我在这里定义了变量:

var activeTab = $(".nav-tabs > li span.open");
var submenu = $(this).siblings("ul");
var thisParent = $(this).closest("ul");

我所要做的就是将activeTab变量更改为:

var thisParent = $(this).closest("ul");
var activeTab = thisParent.children().children("span.open");
var submenu = $(this).siblings("ul");

完美的作品!现在这段代码适用于所有菜单,我不必重复自己!

答案 1 :(得分:1)

您正在寻找$(this).offset();它会告诉您元素相对于文档的位置,因此您需要减去导航栏的位置以获取元素的TOP位置。由于您要在单击元素下方显示菜单,您还必须将单击元素的高度添加到TOP位置以将其推到下方。有关工作和注释的代码,请参阅此代码段

编辑:这是答案的一部分(OP在评论中提出)作为答案发布,所以我可以添加runnable片段。还折叠了代码段,因此它不会占用太多空间。

&#13;
&#13;
$(document).ready(function() {

  $(".nav-tabs span").click(function() {
    var activeTab = $(".nav-tabs > li span.open");
    var submenu = $(this).siblings("ul");
    var thisParent = $(this).closest("ul");
    /*calculate the offset*/
    var offset = $(this).offset(); //gets the offset relative to document
    var parentOffset = $('#navbar').offset(); //get the navbar offset relative to doc
    var heightOfClickedElement = $(this).outerHeight();
    var relativeOffsetTop = offset.top - parentOffset.top + heightOfClickedElement;
    $('.sub-menu').css('top', relativeOffsetTop + 'px');
    /*done calculating the offset */
    if (thisParent.hasClass("nav-tabs")) {

      if (!$(this).is(activeTab)) {
        /*
					alert("this link was not active yet");
					*/
        activeTab.siblings("ul").slideUp();
        submenu.find("span+ul").hide();
        activeTab.removeClass("open");
        $(this).addClass("open");
        submenu.slideDown();

      } else {
        /*
					alert("this link is already active");
					*/
        submenu.slideUp();
        submenu.find("span+ul").hide();
        $(this).removeClass("open");
      }
    } else {
      $(this).toggleClass("open");
      submenu.slideToggle("fast", function() {
        if (!$(this).is(".open")) {
          submenu.find("span+ul").removeClass("open").hide();
        }
      });

    }


  });

});
&#13;
#navbar {
  display: block;
  clear: both;
  width: 100%;
  height: auto;
  margin: 0px;
  padding: 0%;
  background-color: #29568F;
  border-bottom: 3px solid #29568F;
}
.nav-tabs {
  display: inline-block;
  position: relative;
  width: 100%;
  background: #29568F;
  margin: 0px 0px;
  padding: 0px;
  list-style-type: none;
  color: white;
  text-decoration: none;
  text-shadow: 2px 2px #000000;
  font: 18px arial, verdana, sans-serif;
}
.nav-tabs li {
  cursor: pointer;
  float: left;
  padding: 10px 20px;
  text-align: center;
  border-right: 1px solid lightgrey;
}
.nav-tabs li:last-child {
  border: 0px;
}
.nav-tabs li:hover {
  background-color: #3399CC;
}
#active {
  background-color: #3399CC;
}
.nav-tabs li a {
  color: white;
  text-decoration: none;
  text-shadow: 2px 2px #000000;
  font: 18px arial, verdana, sans-serif;
}
/*
	.arrow-down {
		display: inline-block;
		float: right;
		margin: 8px 0px 0px 8px;
		content: url("/images/arrow-down.png");
	}*/

<----------Horizontal Sub-Menu-----------------------> .nav-tabs li .sub-menu {
  display: none;
}
/*
	.nav-tabs li:hover .sub-menu {
		display: block;
	}*/

.sub-menu {
  display: none;
  z-index: 200;
  width: 100%;
  background-color: #3399CC;
  position: absolute;
  top: 41px;
  left: 0px;
  padding: 0px;
  border-bottom: 3px solid #29568F;
}
.sub-menu li {
  list-style-type: none;
  position: relative;
  border: 0px;
  left: 5%;
}
.sub-menu li:hover {
  background-color: #C9EAF3;
}
.sub-menu li:hover a {
  color: #000000;
  text-shadow: 2px 2px #ffffff;
}
<---------------Drop Down Sub-Menu----------------------> .sub-menu li .drop-menu {
  display: none;
}
/*
	.sub-menu li:hover .drop-menu {
		display: block;
	}*/

.drop-menu {
  display: none;
  position: absolute;
  top: 100000px;
  left: -3px;
  margin: 0px;
  padding: 0px;
  background-color: #C9EAF3;
  /*
		width: 120%;*/
  min-width: 220px;
  z-index: 200;
}
.drop-menu li {
  border-bottom: 1px solid #ffffff;
  border-right: 3px solid #29568F;
  border-left: 3px solid #29568F;
  list-style-type: none;
  position: relative;
  left: 0px;
  margin: 0px;
  padding: 10px 1%;
  width: 95%;
  text-indent: 10px;
  text-align: left;
  text-shadow: none !important;
  color: black;
  font-size: 15px;
}
.drop-menu li a {
  text-shadow: none !important;
  color: black;
  font-size: 15px;
}
.drop-menu li:last-child {
  border-bottom: 3px solid #29568F;
  border-right: 3px solid #29568F;
  border-left: 3px solid #29568F;
}
.drop-menu li:hover {
  background-color: #ffffff;
}
<-----------------Slide Out Sub-Menu------------------------> .drop-menu li .slide-menu {
  display: none;
}
/*
	.drop-menu li:hover .slide-menu {
		display: block;
	}*/

.slide-menu {
  display: none;
  position: absolute;
  top: 0px;
  left: 213px;
  margin: 0px;
  padding: 0px;
  width: 120%;
  background-color: white;
  border-top: 3px solid #29568F;
}
.slide-menu:first-child {
  border-top: 0px;
}
.slide-menu li {
  border-right: 3px solid #29568F;
  border-left: 3px solid #29568F;
  list-style-type: none;
  margin: 0px;
  padding: 10px 1%;
  width: 96%;
  text-indent: 10px;
}
.slide-menu li:first-child {
  border-left: 0px;
  position: relative;
  left: 3px;
}
.slide-menu li:hover a {
  text-decoration: underline;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navbar">
  <ul class="nav-tabs">
    <li><span>Home</span>
    </li>
    <li id="active"><span>Dogs <div class="arrow-down"></div></span>

      <ul class="sub-menu">
        <li><span>Meet the Breeds<div class="arrow-down"></div></span>

          <ul class="drop-menu">
            <li><span>Sort A - Z ~ </span>

              <ul class="slide-menu">
                <li>Breeds A - F</li>
                <li>Breeds G - L</li>
                <li>Breeds M - R</li>
                <li>Breeds S - Z</li>
              </ul>
            </li>
            <li><span>Sort by AKC Group ~</span>

              <ul class="slide-menu">
                <li>Sporting Group</li>
                <li>Working Group</li>
                <li>Herding Group</li>
                <li>Hound Group</li>
                <li>Terrier Group</li>
                <li>Non-Sporting Group</li>
                <li>Toy Group</li>
              </ul>
            </li>
            <li><span>Sort by Size ~</span>

              <ul class="slide-menu">
                <li>X-Small (&le 10in)</li>
                <li>Small (10in &gt &lt 15in)</li>
                <li>Medium (15in &ge &lt 21in)</li>
                <li>Large (21in &ge &lt 28in)</li>
                <li>X-Large (28in +)</li>
              </ul>
            </li>
            <li><span>Sort by Coat ~</span>

              <ul class="slide-menu">
                <li>Very Short/Hairless</li>
                <li>Short Coat</li>
                <li>Medium Coats</li>
                <li>Long Coats</li>
                <li>Non-Shedding Coats</li>
                <li>Curly Coats</li>
              </ul>
            </li>
            <li><span>Sort by Trait ~</span>

              <ul class="slide-menu">
                <li>Apartment Suitable</li>
                <li>Laid Back</li>
                <li>Athletic</li>
                <li>Protective</li>
                <li>Extroverted</li>
                <li>Pet Friendly</li>
                <li>Cuddle-Buddies</li>
              </ul>
            </li>
          </ul>
        </li>
        <li><span>Supplies<div class="arrow-down"></div></span>

          <ul class="drop-menu">
            <li><span>Crates & Kennels</li>
                        <li><span>Bowls & Dishes</li>
                        <li><span>Collars & Leashes</li>
                        <li><span>Toys & Games</li>
                        <li><span>Grooming</li>
                        <li><span>Apparal & Accessories</li>
                    </ul>
                </li>
                <li><span>Finding a Dog<div class="arrow-down"></div></span>
            </li>
          </ul>
        </li>
        <li><span>Cats<div class="arrow-down"></div></span>

          <ul class="sub-menu">
            <li><span>Cat Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Cat Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Cat Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Cat Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Cat Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Cat Links<div class="arrow-down"></div></span>
            </li>
          </ul>
        </li>
        <li><span>Birds<div class="arrow-down"></div></span>

          <ul class="sub-menu">
            <li><span>Bird Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Bird Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Bird Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Bird Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Bird Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Bird Links<div class="arrow-down"></div></span>
            </li>
          </ul>
        </li>
        <li><span>Small Mammals<div class="arrow-down"></div></span>

          <ul class="sub-menu">
            <li><span>Sm.Mammal Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Sm.Mammal Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Sm.Mammal Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Sm.Mammal Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Sm.Mammal Links<div class="arrow-down"></div></span>
            </li>
            <li>
              <="#" <span>More Links
                <div class="arrow-down"></div>
                </span>
            </li>
          </ul>
        </li>
        <li><span>Articles<div class="arrow-down"></div></span>

          <ul class="sub-menu">
            <li><span>Article Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Article Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Article Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Article Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Article Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Article Links<div class="arrow-down"></div></span>
            </li>
          </ul>
        </li>
        <li><span>Videos<div class="arrow-down"></div></span>

          <ul class="sub-menu">
            <li><span>Video Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Video Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Video Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Video Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Video Links<div class="arrow-down"></div></span>
            </li>
            <li><span>Video Links<div class="arrow-down"></div></span>
            </li>
          </ul>
        </li>
        <li><span>Updates<div class="arrow-down"></div></span>

          <ul class="sub-menu">
            <li><span>More Links<div class="arrow-down"></div></span>
            </li>
            <li><span>More Links<div class="arrow-down"></div></span>
            </li>
            <li><span>More Links<div class="arrow-down"></div></span>
            </li>
            <li><span>More Links<div class="arrow-down"></div></span>
            </li>
            <li><span>More Links<div class="arrow-down"></div></span>
            </li>
            <li><span>More Links<div class="arrow-down"></div></span>
            </li>
          </ul>
        </li>
      </ul>
</div>
&#13;
&#13;
&#13;