如何创建一个简单的三级jQuery Accordion菜单?

时间:2015-06-30 11:58:30

标签: jquery html menu accordion

你能帮我制作一个三级jQuery手风琴菜单吗?

我有一个功能很好的两级手风琴,但增加第三级已被证明是一个问题。

菜单HTML非常简单,有三个级别的UL:

<ul class="accordion">
<li><a href="#">1</a>
    <ul>
        <li><a href="#">2</a>
            <ul>
                <li><a href="#">3</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">3</a></li>
            </ul>
        </li>
    </ul>
</li>
<li><a href="#">1</a>
    <ul>
        <li><a href="#">2</a>
            <ul>
                <li><a href="#">3</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">3</a></li>
            </ul>
        </li>
    </ul>
</li>
<li><a href="#">1</a>
    <ul>
        <li><a href="#">2</a>
            <ul>
                <li><a href="#">3</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">3</a></li>
            </ul>
        </li>
    </ul>
</li>
</ul>

调用的脚本是jquery 1.9.1和jquery ui 1.9.2,菜单使用了accordion函数。

菜单以:

开始
$(function() {
   $( ".accordion" ).accordion({    
      autoHeight: false,
      navigation: true,
      active: false
   });
});

但是当我添加第三级时,所有级别的项目都保持打开并可点击。

我花了相当多的时间阅读Accordion文档,但找不到制作第三级功能的方法。

当我尝试双重定位时,我让菜单运行(正确滑动),但是我无法点击第三级的链接!

$(function() {
   $( ".accordion, .accordion ul" ).accordion({ 
      autoHeight: false,
      navigation: true,
      active: false
   });
});

3 个答案:

答案 0 :(得分:1)

这是创建多级Jquery Accordion菜单的一种非常简单的方法

JS小提琴链接:http://jsfiddle.net/abidkhanweb/pwhz1zc4/

( function( $ ) {
$( document ).ready(function() {
$('#cssmenu li.has-sub>a').on('click', function(){
		$(this).removeAttr('href');
		var element = $(this).parent('li');
		if (element.hasClass('open')) {
			element.removeClass('open');
			element.find('li').removeClass('open');
			element.find('ul').slideUp();
		}
		else {
			element.addClass('open');
			element.children('ul').slideDown();
			element.siblings('li').children('ul').slideUp();
			element.siblings('li').removeClass('open');
			element.siblings('li').find('li').removeClass('open');
			element.siblings('li').find('ul').slideUp();
		}
	});

	$('#cssmenu>ul>li.has-sub>a').append('<span class="holder"></span>');

	(function getColor() {
		var r, g, b;
		var textColor = $('#cssmenu').css('color');
		textColor = textColor.slice(4);
		r = textColor.slice(0, textColor.indexOf(','));
		textColor = textColor.slice(textColor.indexOf(' ') + 1);
		g = textColor.slice(0, textColor.indexOf(','));
		textColor = textColor.slice(textColor.indexOf(' ') + 1);
		b = textColor.slice(0, textColor.indexOf(')'));
		var l = rgbToHsl(r, g, b);
		if (l > 0.7) {
			$('#cssmenu>ul>li>a').css('text-shadow', '0 1px 1px rgba(0, 0, 0, .35)');
			$('#cssmenu>ul>li>a>span').css('border-color', 'rgba(0, 0, 0, .35)');
		}
		else
		{
			$('#cssmenu>ul>li>a').css('text-shadow', '0 1px 0 rgba(255, 255, 255, .35)');
			$('#cssmenu>ul>li>a>span').css('border-color', 'rgba(255, 255, 255, .35)');
		}
	})();

	function rgbToHsl(r, g, b) {
	    r /= 255, g /= 255, b /= 255;
	    var max = Math.max(r, g, b), min = Math.min(r, g, b);
	    var h, s, l = (max + min) / 2;

	    if(max == min){
	        h = s = 0;
	    }
	    else {
	        var d = max - min;
	        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
	        switch(max){
	            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
	            case g: h = (b - r) / d + 2; break;
	            case b: h = (r - g) / d + 4; break;
	        }
	        h /= 6;
	    }
	    return l;
	}
});
} )( jQuery );
#cssmenu,
#cssmenu ul,
#cssmenu ul li,
#cssmenu ul li a {
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
  line-height: 1;
  display: block;
  position: relative;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
#cssmenu {
  width: 200px;
  font-family: Helvetica, Arial, sans-serif;
  color: #ffffff;
}
#cssmenu ul ul {
  display: none;
}
.align-right {
  float: right;
}
#cssmenu > ul > li > a {
  padding: 15px 20px;
  border-left: 1px solid #1682ba;
  border-right: 1px solid #1682ba;
  border-top: 1px solid #1682ba;
  cursor: pointer;
  z-index: 2;
  font-size: 14px;
  font-weight: bold;
  text-decoration: none;
  color: #ffffff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
  background: #36aae7;
  background: -webkit-linear-gradient(#36aae7, #1fa0e4);
  background: -moz-linear-gradient(#36aae7, #1fa0e4);
  background: -o-linear-gradient(#36aae7, #1fa0e4);
  background: -ms-linear-gradient(#36aae7, #1fa0e4);
  background: linear-gradient(#36aae7, #1fa0e4);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15);
}
#cssmenu > ul > li > a:hover,
#cssmenu > ul > li.active > a,
#cssmenu > ul > li.open > a {
  color: #eeeeee;
  background: #1fa0e4;
  background: -webkit-linear-gradient(#1fa0e4, #1992d1);
  background: -moz-linear-gradient(#1fa0e4, #1992d1);
  background: -o-linear-gradient(#1fa0e4, #1992d1);
  background: -ms-linear-gradient(#1fa0e4, #1992d1);
  background: linear-gradient(#1fa0e4, #1992d1);
}
#cssmenu > ul > li.open > a {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.15);
  border-bottom: 1px solid #1682ba;
}
#cssmenu > ul > li:last-child > a,
#cssmenu > ul > li.last > a {
  border-bottom: 1px solid #1682ba;
}
.holder {
  width: 0;
  height: 0;
  position: absolute;
  top: 0;
  right: 0;
}
.holder::after,
.holder::before {
  display: block;
  position: absolute;
  content: "";
  width: 6px;
  height: 6px;
  right: 20px;
  z-index: 10;
  -webkit-transform: rotate(-135deg);
  -moz-transform: rotate(-135deg);
  -ms-transform: rotate(-135deg);
  -o-transform: rotate(-135deg);
  transform: rotate(-135deg);
}
.holder::after {
  top: 17px;
  border-top: 2px solid #ffffff;
  border-left: 2px solid #ffffff;
}
#cssmenu > ul > li > a:hover > span::after,
#cssmenu > ul > li.active > a > span::after,
#cssmenu > ul > li.open > a > span::after {
  border-color: #eeeeee;
}
.holder::before {
  top: 18px;
  border-top: 2px solid;
  border-left: 2px solid;
  border-top-color: inherit;
  border-left-color: inherit;
}
#cssmenu ul ul li a {
  cursor: pointer;
  border-bottom: 1px solid #32373e;
  border-left: 1px solid #32373e;
  border-right: 1px solid #32373e;
  padding: 10px 20px;
  z-index: 1;
  text-decoration: none;
  font-size: 13px;
  color: #eeeeee;
  background: #49505a;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
#cssmenu ul ul li:hover > a,
#cssmenu ul ul li.open > a,
#cssmenu ul ul li.active > a {
  background: #424852;
  color: #ffffff;
}
#cssmenu ul ul li:first-child > a {
  box-shadow: none;
}
#cssmenu ul ul ul li:first-child > a {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
#cssmenu ul ul ul li a {
  padding-left: 30px;
}
#cssmenu > ul > li > ul > li:last-child > a,
#cssmenu > ul > li > ul > li.last > a {
  border-bottom: 0;
}
#cssmenu > ul > li > ul > li.open:last-child > a,
#cssmenu > ul > li > ul > li.last.open > a {
  border-bottom: 1px solid #32373e;
}
#cssmenu > ul > li > ul > li.open:last-child > ul > li:last-child > a {
  border-bottom: 0;
}
#cssmenu ul ul li.has-sub > a::after {
  display: block;
  position: absolute;
  content: "";
  width: 5px;
  height: 5px;
  right: 20px;
  z-index: 10;
  top: 11.5px;
  border-top: 2px solid #eeeeee;
  border-left: 2px solid #eeeeee;
  -webkit-transform: rotate(-135deg);
  -moz-transform: rotate(-135deg);
  -ms-transform: rotate(-135deg);
  -o-transform: rotate(-135deg);
  transform: rotate(-135deg);
}
#cssmenu ul ul li.active > a::after,
#cssmenu ul ul li.open > a::after,
#cssmenu ul ul li > a:hover::after {
  border-color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <div id='cssmenu'>
<ul>
   <li><a href='#'><span>Home</span></a></li>
   <li class='active has-sub'><a href='#'><span>Products</span></a>
      <ul>
         <li class='has-sub'><a href='#'><span>Product 1</span></a>
            <ul>
               <li><a href='#'><span>Sub Product</span></a></li>
               <li class='last has-sub'><a href='#'><span>Sub Product</span></a>
               	
                    <ul>
                       <li><a href='#'><span>Sub Product</span></a></li>
                       <li class='last'><a href='#'><span>Sub Product</span></a></li>
                    </ul>
      
               </li>
            </ul>
         </li>
         <li><a href='#'><span>Product 2</span></a></li>
      </ul>
   </li>
   <li><a href='#'><span>About</span></a></li>
   <li class='last'><a href='#'><span>Contact</span></a></li>
</ul>
</div>

答案 1 :(得分:0)

尝试添加collapsible:true,它可能适合您。

演示:http://jsfiddle.net/GCu2D/756/

$(function () {
    $("ul").accordion({
        autoHeight: false,
        navigation: true,
        active: false,
        collapsible: true
    });
});

答案 2 :(得分:0)

我花了相当多的时间思考这个问题,最终解决方案变得更加简单。

首先需要为所有UL元素启动手风琴:

$( ".accordion ul ul ul" ).accordion( "destroy" );

销毁手风琴,用于需要激活的链接级别(点击时激活)。

<强> import UIKit import EventKit extension RangeReplaceableCollectionType where Generator.Element : Equatable { mutating func removeObject(object : Generator.Element) { if let index = self.indexOf(object) { self.removeAtIndex(index) } } } class EventsViewController: UIViewController { var calendarName:String! var currentStat = Stat() var eventStore = EKEventStore() //represents the Calendar database. Point of contact for accessing calendar var icloudEventSource: EKSource? //represents the account that a calendar belongs to. var startDate=NSDate().dateByAddingTimeInterval(-31556926) var endDate=NSDate().dateByAddingTimeInterval(31556926) var yourCalendar: EKCalendar? var calendar: EKCalendar? //represents a calendar in Event Kit var numberOfCalendars : Int = 0 var calendarsArray = NSMutableArray() var calendarsPrueba : [EKCalendar]? var calendarioSeleccionado:String! var delegate: passDataBackDelegate? var events : [EKEvent]! var tableView : UITableView? var selectedMarks = [StatEvents]() var selectedIndex = [NSIndexPath]() var orderedStatEvents = [StatEvents]() @IBOutlet weak var segmentedControl: UISegmentedControl! @IBOutlet weak var textLabel: UILabel! @IBAction func indexChanged(sender: UISegmentedControl) { switch segmentedControl.selectedSegmentIndex { case 0: orderTable(0) case 1: orderTable(1) default: break; } } func orderTable(order: Int) { switch order { case 0: currentStat.statEvents.sortInPlace({ $0.name.compare($1.name) == NSComparisonResult.OrderedAscending }) case 1: currentStat.statEvents.sortInPlace({ $0.name.compare($1.name) == NSComparisonResult.OrderedDescending }) default: break; } tableView?.reloadData() } override func viewDidLoad() { super.viewDidLoad() eventStore.requestAccessToEntityType(EKEntityType.Event, completion: {(granted: Bool, error:NSError?) in if !granted { print("Access to store not granted") } }) // Buscamos la cuenta de iCloud que contiene los calendarios for source in eventStore.sources{ if source.sourceType.rawValue == EKSourceType.CalDAV.rawValue && source.title.lowercaseString == "icloud"{ icloudEventSource = source } } ///////Mostramos solo calendarios de iCloud////// if (icloudEventSource != nil){ let calendars = icloudEventSource!.calendarsForEntityType(EKEntityType.Event) print("1 The iCloud event source was found = \(icloudEventSource!.title)") print("1 Number of calendars = \(calendars.count)") for calendars in calendars{ yourCalendar = (calendars as EKCalendar) print(yourCalendar!.title) calendarsArray.addObject(yourCalendar!.title) } }else{ print("Could not find the iCloud event source") } //////Mostramos todos los calendarios/////// let calendars = eventStore.calendarsForEntityType(EKEntityType.Event) //Devuelve los calendarios que son eventos numberOfCalendars = calendars.count print("Number of calendars = \(calendars.count)") for calendars in calendars as [EKCalendar] { print("events = \(calendars.title)") calendarsArray.addObject(calendars.title) } func calendarEventsWithName( name:String ) -> [EKCalendar]? { let calendars = eventStore.calendarsForEntityType(EKEntityType.Event) as [EKCalendar] for cal in calendars { if cal.title == name { return [cal] } } print ("failed to find calendar") return nil } let predicate = eventStore.predicateForEventsWithStartDate(startDate, endDate: endDate, calendars: calendarEventsWithName(currentStat.statCalendar)) print("startDate:\(startDate) endDate:\(endDate)") events = eventStore.eventsMatchingPredicate(predicate) as [EKEvent]! let calendar = NSCalendar.currentCalendar() let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "dd-MM-yyyy" //format style. Browse online to get a format that fits your needs. if events != nil { print(events.count) for i in events { let components = calendar.components(.Hour, fromDate: i.startDate, toDate: i.endDate, options: []) currentStat.statEvents.append(StatEvents(name: i.title, dateRanges: [i.startDate, i.endDate], hours: components.hour)) } } else { print("No hay eventos en este calendario") } } // MARK: - Table view data source func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return events.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as UITableViewCell tableView.allowsMultipleSelection = true cell.textLabel?.font = UIFont.systemFontOfSize(8.0) cell.textLabel?.text = "\(currentStat.statEvents[indexPath.row].name) \(currentStat.statEvents[indexPath.row].dateRanges) horas=\(currentStat.statEvents[indexPath.row].hours)" if let selectedPaths = tableView.indexPathsForSelectedRows { let selected = selectedPaths.filter(){ $0 == indexPath } if selected.count > 0 { cell.accessoryType = .Checkmark } else { cell.accessoryType = .None } } return cell } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if (selectedMarks.contains(currentStat.statEvents[indexPath.row])){ if let cell = tableView.cellForRowAtIndexPath(indexPath) { cell.accessoryType = .None } print("borro") selectedMarks.removeObject(currentStat.statEvents[indexPath.row]) } else { if let cell = tableView.cellForRowAtIndexPath(indexPath) { cell.accessoryType = .Checkmark } print("añado") selectedMarks.append(currentStat.statEvents[indexPath.row]) //add the object to selectedMarks } selectedIndex = tableView.indexPathsForSelectedRows! tableView.reloadData() } @IBAction func done(sender: AnyObject) { selectedMarks.sortInPlace({ $0.dateRanges[0].compare($1.dateRanges[0]) == NSComparisonResult.OrderedAscending }) currentStat.statEvents = selectedMarks navigationController!.popViewControllerAnimated(true) }

就是这样。 : - )