Accordions are useful for displaying large amounts of different parts of data in a small space. jQuery UI has a built-in Accordion function, but according to jQuery UI Build your Download, the size of the Core jQuery UI and Accordion scripts are 25kb and 16.6kb respectively. Today I'm going to show you how to build a more "bandwidth efficient" custom accordion.
Download attachments from the sidebar to view.
This may seem like a lot for a simple accordion. Especially when you add a normal jQuery script, which is minified and compressed to 18kb. So instead of adding extra unnecessary functionality to your page load time, why not create something from scratch?
I also think that writing something from scratch really gives you a better understanding of how to use jQuery effectively without always having to resort to using someone else's code.
So the plan for this tutorial is to show creating an accordion using jQuery UI functions and then using some custom coding to create one. Let’s take a blog sidebar as an example.
tag is very simple, just a list item for each section in the accordion:
<ul id="accordion"> <li> <a href="#recent" class="heading">Recent Entries</a> <ul id="recent"> <li><span class="date">01.19.2009</span> <a href="#">Recent Entry Title</a></li> <li><span class="date">01.15.2009</span> <a href="#">Recent Entry Title</a></li> <li><span class="date">01.13.2009</span> <a href="#">Recent Entry Title</a></li> <li><span class="date">01.11.2009</span> <a href="#">Recent Entry Title</a></li> <li><span class="date">01.10.2009</span> <a href="#">Recent Entry Title</a></li> </ul> </li> <li> <a href="#popular" class="heading">Popular Entries</a> <ul id="popular"> <li><span class="date">08.16.2008</span> <a href="#">Popular Entry Title</a></li> <li><span class="date">06.12.2008</span> <a href="#">Popular Entry Title</a></li> <li><span class="date">04.12.2008</span> <a href="#">Popular Entry Title</a></li> <li><span class="date">06.12.2007</span> <a href="#">Popular Entry Title</a></li> <li><span class="date">03.12.2007</span> <a href="#">Popular Entry Title</a></li> </ul> </li> <li> <a href="#categories" class="heading">Categories</a> <ul id="categories"> <li><a href="#">Category Name</a> <span class="count">7</span></li> <li><a href="#">Category Name</a> <span class="count">4</span></li> <li><a href="#">Category Name</a> <span class="count">15</span></li> <li><a href="#">Category Name</a> <span class="count">29</span></li> <li><a href="#">Category Name</a> <span class="count">8</span></li> </ul> </li> <li> <a href="#archive" class="heading">Archive</a> <ul id="archive"> <li><a href="#">January 2009</a> <span class="count">4</span></li> <li><a href="#">December 2008</a> <span class="count">14</span></li> <li><a href="#">November 2008</a> <span class="count">12</span></li> <li><a href="#">October 2008</a> <span class="count">8</span></li> <li><a href="#">September 2008</a> <span class="count">18</span></li> </ul> </li> </ul>
We are going to add some very basic styles to make the accordion look nicer. Since this tutorial is mainly focused on JavaScript, I'll give you a quick overview of what we're doing with CSS.
Since I always start with my own simple frame stylesheet, I will use that here as well:
/*****Reset*****/ html, body, div, h1, h3, h3, h4, h5, h6, ul, ol, dl, li, dt, dd, p, blockquote, pre, form, fieldset, table, th, td { margin: 0; padding: 0; } /*****Basic Definitions*****/ body { background: #fff; color: #333; font: 14px/20px Georgia, "Times New Roman", Times, serif; } h1 { font-size: 24px; line-height: 30px; margin-bottom: 18px; } a { } a:visited { } a:hover { text-decoration: none; } img { border: none; } p, ul, ol, dl, table { margin-bottom: 18px; } ul, ol, dd { margin-left: 36px; } /*****Custom Classes*****/ .clearing { clear: both; } .clearfix { overflow: hidden; } .last { margin-bottom: 0; } .screenReader { left: -9999px; position: absolute; top: -9999px; }
Next, I'll remove the margins and list styles from the accordion unordered list and descendant list, and add a bottom border to the accordion unordered list (you'll soon understand why it's just a bottom border). < /p>
ul#accordion, ul#accordion ul { list-style: none; margin: 0; } ul#accordion { border-bottom: 1px solid #000E2E; }
I will then add a border around each accordion section (except the bottom border). Also, I will remove the borders from the descendant list items of the accordion section and add only the bottom border. If it is the last child of an unordered list of descendants, I remove the bottom border. Yes, I know this doesn't work in IE, but it's not necessary.
ul#accordion li { border: 1px solid #000E2E; border-bottom: none; } ul#accordion ul li { border: none; border-bottom: 1px solid #C2C8D1; color: #999; padding: 5px 10px; } ul#accordion ul li:last-child { border-bottom: none; }
Next, I'll style the main links that will toggle the accordions so they stand out more:
ul#accordion a.heading { background: #F4FFF9; color: #999; display: block; font-size: 18px; line-height: 18px; padding: 10px 5px; text-decoration: none; } ul#accordion a.heading:hover { background: #00B9D2; color: #fff; }
Finally, I'm going to do some basic styling on the accordions' sublists so they look a little nicer:
ul#accordion li ul a { border-bottom: 1px solid #00B9D2; color: #025185; text-decoration: none; } ul#accordion li ul a:hover { border-bottom: none; } ul#accordion li ul .date { padding-right: 10px; } ul#accordion li ul .count { padding-left: 10px; }
Let's take a look at our progress so far. This is also what the accordion looks like when we use jQuery UI Accordion and JavaScript is disabled.
Looks like we need to add some extra CSS for IE6 to resolve the whitespace error:
ul#accordion { float: left; width: 300px; } ul#accordion li { float: left; width: 298px; } ul#accordion a.heading { width: 298px; } ul#accordion ul li { float: none; width: auto; }
Now that we have all the markup and styling done, implementing the jQuery UI accordion is very simple. First, we just need to include the jQuery and jQuery UI scripts.
<script type="text/javascript" src="scripts/jquery.js"></script> <script type="text/javascript" src="scripts/jquery-ui-accordion.js"></script>
Then, we need to initialize the Accordion in the unordered list using the Accordion's id:
<script type="text/javascript"> $(document).ready(function() { $('#accordion').accordion(); }); </script>
Now you have it, a working accordion.
To make the currently open accordion project stand out more, I added some extra CSS:
ul#accordion li.ui-accordion-selected a.heading { background: #025185; color: #fff; }
ui-accordion-selected is automatically added to the current collapsed section.
Now that we have completed the jQuery UI accordion, it's time to create our own. One thing I don't necessarily like about the jQuery UI version is the way it displays when JavaScript is disabled. I want to open only one section at a time.
To achieve this, I'm going to add a little bit of PHP. You can also easily accomplish this task using any programming language.
The idea behind this is that we will pass a variable in the URL and if that variable is consistent with each part, we will assign a current class to that part. It's easier to see this in code, so take a look:
<?php $section = $_GET['section']; ?> <ul id="accordion"> <li<?php if($section == '' || $section == 'recent'): ?> class="current"<?php endif; ?>> <a href="?section=recent" class="heading">Recent Entries</a> <ul id="recent"> <li><span class="date">01.19.2009</span> <a href="#">Recent Entry Title</a></li> <li><span class="date">01.15.2009</span> <a href="#">Recent Entry Title</a></li> <li><span class="date">01.13.2009</span> <a href="#">Recent Entry Title</a></li> <li><span class="date">01.11.2009</span> <a href="#">Recent Entry Title</a></li> <li><span class="date">01.10.2009</span> <a href="#">Recent Entry Title</a></li> </ul> </li> <li<?php if($section == 'popular'): ?> class="current"<?php endif; ?>> <a href="?section=popular" class="heading">Popular Entries</a> <ul id="popular"> <li><span class="date">08.16.2008</span> <a href="#">Popular Entry Title</a></li> <li><span class="date">06.12.2008</span> <a href="#">Popular Entry Title</a></li> <li><span class="date">04.12.2008</span> <a href="#">Popular Entry Title</a></li> <li><span class="date">06.12.2007</span> <a href="#">Popular Entry Title</a></li> <li><span class="date">03.12.2007</span> <a href="#">Popular Entry Title</a></li> </ul> </li> <li<?php if($section == 'categories'): ?> class="current"<?php endif; ?>> <a href="?section=categories" class="heading">Categories</a> <ul id="categories"> <li><a href="#">Category Name</a> <span class="count">7</span></li> <li><a href="#">Category Name</a> <span class="count">4</span></li> <li><a href="#">Category Name</a> <span class="count">15</span></li> <li><a href="#">Category Name</a> <span class="count">29</span></li> <li><a href="#">Category Name</a> <span class="count">8</span></li> </ul> </li> <li<?php if($section == 'archive'): ?> class="current"<?php endif; ?>> <a href="?section=archive" class="heading">Archive</a> <ul id="archive"> <li><a href="#">January 2009</a> <span class="count">4</span></li> <li><a href="#">December 2008</a> <span class="count">14</span></li> <li><a href="#">November 2008</a> <span class="count">12</span></li> <li><a href="#">October 2008</a> <span class="count">8</span></li> <li><a href="#">September 2008</a> <span class="count">18</span></li> </ul> </li> </ul>
You should also notice that I changed the URL of each link in the toggle accordion section to match that section's if statement. So basically, if JavaScript is disabled, you will be taken to a new page that opens that section.
We also need to remove the jQuery UI accordion script and include our own:
<script type="text/javascript" src="scripts/accordion.js"></script>
With a slight change to the markup, we need to add some additional CSS. We no longer assign the ui-accordion-selected class to the list item; it is now a class currently. We also have to consider class name changes when the accordion is open:
ul#accordion li.current a.heading { background: #025185; color: #fff; }
所以我们想要做的是隐藏所有无序列表,除非它们是具有 current 类的列表项的后代。我还在这个演示页面中添加了一个 body id,以便我们可以为这两个示例使用相同的样式表。
body#customAccordion ul#accordion li ul { display: none; } body#customAccordion ul#accordion li.current ul { display: block; }
首先,我们希望在文档加载后执行脚本,因此我们从以下开始:
$(document).ready(function() { });
我们希望手风琴在单击标题链接时起作用,但我们不想离开页面,因此我们需要确保并返回 false:
$(document).ready(function() { $('ul#accordion a.heading').click(function() { return false; }); });
接下来,我不喜欢单击链接时在链接周围显示的轮廓,因此我将其设置为“无”:
$(document).ready(function() { $('ul#accordion a.heading').click(function() { $(this).css('outline','none'); return false; }); });
此脚本有两种不同的情况。
这不是 jQuery UI 版本具有的功能,但我认为用户应该能够根据需要关闭所有部分。如果单击的链接的父级具有 current 类,我们希望向上滑动无序列表并删除 current 类。
$(document).ready(function() { $('ul#accordion a.heading').click(function() { $(this).css('outline','none'); if($(this).parent().hasClass('current')) { $(this).siblings('ul').slideUp('slow',function() { $(this).parent().removeClass('current'); }); } return false; }); });
jQuery UI 版本让我烦恼的另一件事是,您可以滚动手风琴,使其几乎看不见,单击它,然后交互发生在您可以看到的上方。向下滚动 jQuery UI 示例并尝试一下。
所以我的解决方案是使用这个名为 jQuery ScrollTo 的美妙小脚本。这是一个非常小的脚本,可以增加平滑的页面滚动。
让我们将其添加到文档头部的手风琴脚本之前:
<script type="text/javascript" src="scripts/accordion.js"></script>
当该部分向上滚动时,我想将窗口滚动到手风琴的顶部:
$(document).ready(function() { $('ul#accordion a.heading').click(function() { $(this).css('outline','none'); if($(this).parent().hasClass('current')) { $(this).siblings('ul').slideUp('slow',function() { $(this).parent().removeClass('current'); $.scrollTo('#accordion',1000); }); } return false; }); });
函数的第一个参数是滚动到的目标,第二个参数是滚动所需的时间。
当单击的部分当前未打开时,就会发生这种情况。所以我们要做的第一件事就是隐藏当前打开的部分并删除 current 的类(这段代码与第一种情况非常相似):
$(document).ready(function() { $('ul#accordion a.heading').click(function() { $(this).css('outline','none'); if($(this).parent().hasClass('current')) { $(this).siblings('ul').slideUp('slow',function() { $(this).parent().removeClass('current'); $.scrollTo('#accordion',1000); }); } else { $('ul#accordion li.current ul').slideUp('slow',function() { $(this).parent().removeClass('current'); }); } return false; }); });
接下来,我们要打开我们单击的部分并添加当前的类:
$(document).ready(function() { $('ul#accordion a.heading').click(function() { $(this).css('outline','none'); if($(this).parent().hasClass('current')) { $(this).siblings('ul').slideUp('slow',function() { $(this).parent().removeClass('current'); $.scrollTo('#accordion',1000); }); } else { $('ul#accordion li.current ul').slideUp('slow',function() { $(this).parent().removeClass('current'); }); $(this).siblings('ul').slideToggle('slow',function() { $(this).parent().toggleClass('current'); }); } return false; }); });
最后,让我们将窗口滚动到手风琴的顶部,就像我们在第一种情况下所做的那样:
$(document).ready(function() { $('ul#accordion a.heading').click(function() { $(this).css('outline','none'); if($(this).parent().hasClass('current')) { $(this).siblings('ul').slideUp('slow',function() { $(this).parent().removeClass('current'); $.scrollTo('#accordion',1000); }); } else { $('ul#accordion li.current ul').slideUp('slow',function() { $(this).parent().removeClass('current'); }); $(this).siblings('ul').slideToggle('slow',function() { $(this).parent().toggleClass('current'); }); $.scrollTo('#accordion',1000); } return false; }); });
就是这样。严重地。您认为创建手风琴就这么简单吗?
现在,让我们使用 Firebug 中的“网络”选项卡比较 JavaScript 文件大小。
在 jQuery UI 示例中,JavaScript 文件总计约为 73 kb。在我们的自定义示例中,随着窗口的额外滚动,JavaScript 文件总数约为 57 kb。现在,这可能看起来不多,但想象一下,如果您有一个流量非常高的网站。这可能会节省很多字节。另外,现在您对 jQuery 有了更多了解。
现在出去编写您自己的 jQuery。
The above is the detailed content of The Ultimate Guide to Making a Personalized jQuery Accordion. For more information, please follow other related articles on the PHP Chinese website!