如何使用 jQuery 对多个手风琴进行正确排序
这是我第一次发帖,所以如果我未能提供足够的详细信息,请告诉我。
我有一个包含多个手风琴的页面。我想使用多个手风琴,因为我希望用户能够同时打开多个部分,这不是手风琴本身的。
我还希望用户能够对这些手风琴进行排序。按照当前页面的设置方式,用户可以毫无问题地对手风琴进行排序。
当用户对手风琴进行排序时,我有一个脚本将关闭所有现有的手风琴,将它们的 id 存储在一个数组中,然后在用户完成排序后重新打开它们。那部分也工作得很好。
当您尝试将要排序的部分放置在之前打开的两个部分之间时,就会出现此问题。当以编程方式关闭它们时,jQuery 似乎无法轻松判断一个部分的开始位置和结束位置。请注意,如果它们已经关闭,则它会按预期工作。
我尝试了几种解决此问题的方法,包括在各部分之间添加间隔 div 以及销毁手风琴,然后在排序完成后重新初始化它们,但无济于事。
我怀疑出现问题是因为当第一次抓住手风琴时,各部分是打开的。但那时,我关闭了所有部分,即使该部分关闭,当您尝试在两个部分之间放置一个部分时,它也会导致这些部分偶尔跳转。
我还注意到手风琴内容的高度因素。在下面的示例中,第一个 div 在打开时会导致问题,并且您尝试对它们进行排序,但其他 div 则不然。
这是我的代码。 jQuery 是基本的 jQuery 库,为了简单起见,我将我编写的内容内联起来:
<html>
<head>
<link href="/css/flick/jquery-ui.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Add Accordion stuff
$(".accordion").accordion({
autoHeight: false,
active: false,
collapsible: true
}); // end $(".accordion").accordion
// Add sortables
$('.sortable').sortable({
start: function(e, ui) {
container = $(e.target);
var parent_id = container.parent().parent().attr('id');
expanded_ones = new Array();
var count = 0;
var summary = '';
var child = '';
var active = '';
// now close all other sections
$.each($('#' + parent_id + ' .accordion'), function() {
// get the child element since that has the div id I need
child = $(this).children('div');
// get the active information to see if it is open or closed
active = $(this).accordion('option', 'active');
// check to see if this one is expanded
if(parseInt(active) == active) {
// store this id so we can open it later
expanded_ones[count] = $(child).attr('id');
count++;
// and close the accordion
$(this).accordion({ active: false });
} // end if(parseInt(active) == active)
}); // end $.each($('#' + parent_id + ' .accordion'), function()
}, // end start: function(e, ui)
stop: function(e, ui) {
container = $(e.target);
var parent_elem = '';
// expand the ones that were originally expanded
for(var i = 0; i < expanded_ones.length; i++) {
parent_elem = $('#' + expanded_ones[i]).parent();
$(parent_elem).accordion('option', 'active', 0);
} // end for(var i = 0; i < expanded_ones; i++)
} // end stop: function(e, ui)
}); // end $('.sortable').sortable
}); // end $(document).ready(function() {
</script>
</head>
<body>
<div id="outer">
<div class="box">
<div class="accordion_wrapper sortable" rel="sections">
<div id="accordion_a" class="section_accordion">
<div class="accordion">
<h4>Accordion A</h4>
<div id="accordion_a_content">
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
</div>
</div>
</div>
<div id="accordion_b" class="section_accordion">
<div class="accordion">
<h4>Accordion B</h4>
<div id="accordion_b_content">
Stuff
</div>
</div>
</div>
<div id="accordion_c" class="section_accordion">
<div class="accordion">
<h4>Accordion C</h4>
<div id="accordion_c_content">
Stuff
</div>
</div>
</div>
<div id="accordion_d" class="section_accordion">
<div class="accordion">
<h4>Accordion D</h4>
<div id="accordion_d_content">
Stuff
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
This is my first time posting so please let me know if I fail to provide enough details.
I have a page that contains multiple accordions. I wanted to use multiple accordions because I wanted users to be able to have multiple sections open at once which is not native to accordion.
I also want users to be able to sort those accordions. The way the page is currently set up, users can sort the accordion with no problems.
When the user goes to sort the accordions, I have a script that will close all existing accordions, store their ids in an array, and then reopen them when the user is done sorting. That part works fine too.
The problem occurs when you try to place the section you are sorting between two sections that were previously open. It does not appear that jQuery can easily tell where one section begins and one ends when they are closed programatically. Note that if they were already closed, it works as expected.
I've tried several approaches to this problem including adding a spacer div between sections as well as destroying the accordions and then reinitializing them after the sorting is finished to no avail.
I suspect the problem occurs because when the accordion is first grabbed, the sections are open. But at that point, I close all the sections and even though the section closes, it causes those sections to jump around sporadically when you try to put a section between two.
I've also noticed that the height of the contents of the accordion factors in. In my example below, the first div causes problems when it is open and you try to sort them but the others less so.
Here is the code I have. The jQuery is the basic jQuery library and the stuff I wrote I included inline for simplicity:
<html>
<head>
<link href="/css/flick/jquery-ui.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Add Accordion stuff
$(".accordion").accordion({
autoHeight: false,
active: false,
collapsible: true
}); // end $(".accordion").accordion
// Add sortables
$('.sortable').sortable({
start: function(e, ui) {
container = $(e.target);
var parent_id = container.parent().parent().attr('id');
expanded_ones = new Array();
var count = 0;
var summary = '';
var child = '';
var active = '';
// now close all other sections
$.each($('#' + parent_id + ' .accordion'), function() {
// get the child element since that has the div id I need
child = $(this).children('div');
// get the active information to see if it is open or closed
active = $(this).accordion('option', 'active');
// check to see if this one is expanded
if(parseInt(active) == active) {
// store this id so we can open it later
expanded_ones[count] = $(child).attr('id');
count++;
// and close the accordion
$(this).accordion({ active: false });
} // end if(parseInt(active) == active)
}); // end $.each($('#' + parent_id + ' .accordion'), function()
}, // end start: function(e, ui)
stop: function(e, ui) {
container = $(e.target);
var parent_elem = '';
// expand the ones that were originally expanded
for(var i = 0; i < expanded_ones.length; i++) {
parent_elem = $('#' + expanded_ones[i]).parent();
$(parent_elem).accordion('option', 'active', 0);
} // end for(var i = 0; i < expanded_ones; i++)
} // end stop: function(e, ui)
}); // end $('.sortable').sortable
}); // end $(document).ready(function() {
</script>
</head>
<body>
<div id="outer">
<div class="box">
<div class="accordion_wrapper sortable" rel="sections">
<div id="accordion_a" class="section_accordion">
<div class="accordion">
<h4>Accordion A</h4>
<div id="accordion_a_content">
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
<p>Stuff</p>
</div>
</div>
</div>
<div id="accordion_b" class="section_accordion">
<div class="accordion">
<h4>Accordion B</h4>
<div id="accordion_b_content">
Stuff
</div>
</div>
</div>
<div id="accordion_c" class="section_accordion">
<div class="accordion">
<h4>Accordion C</h4>
<div id="accordion_c_content">
Stuff
</div>
</div>
</div>
<div id="accordion_d" class="section_accordion">
<div class="accordion">
<h4>Accordion D</h4>
<div id="accordion_d_content">
Stuff
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先我想说,这真的需要手风琴或可排序吗?其次,我在此处设置了您的示例。使用此示例,可排序可以将页面发送到各处,尤其是当手风琴 A 打开时。这可能会让一些用户感到非常困惑。我建议寻找另一种选择来完成您的任务。
来自 jQueries 网站 Accordian 上的 API
因此,如果您想打开多个可排序的手风琴,我建议您创建自己的自定义代码。
Firstly i would say, does this really need to be in accordians or sortable? Secondly i set up your example here. Using this example the sortable can send the page all over the place especially when accordian A is open. This can be extremely confusing to some users. I would recommend finding another option to complete your task.
From jQueries website API on Accordian
So i would recommend creating your own custom code if you want to have multiple accordians open that are sortable.
这篇文章向您展示如何在手风琴上同时打开多个部分。 寻找 JQuery类似于 Accordian 的插件,但允许同时打开多个部分
This post shows you how to have multiple sections open at once on an accordion. Looking for a JQuery plug-in similar to Accordian, but that allows multiple sections open at once