【问题标题】:Refresh child in dynamically created nested accordion在动态创建的嵌套手风琴中刷新孩子
【发布时间】:2014-02-06 03:10:25
【问题描述】:

当用户单击按钮时,我试图将项目动态附加到嵌套手风琴。我正在使用以下代码创建嵌套手风琴:

  $(".accordion").accordion({
  collapsible: true, 
  autoHeight: false, 
  animated: 'swing',
  heightStyle: "content",
  changestart: function(event, ui) {
      child.accordion("activate", false);
  }
});

var child = $(".child-accordion").accordion({
  active:false,
  collapsible: true, 
  autoHeight: false,
  animated: 'swing'
});

为了做到这一点,我发现我需要使用以下方法刷新手风琴:

$('.accordion').accordion("refresh");

我的问题是,当我尝试使用以下方法刷新内部手风琴时:

$('.child-accordion').accordion("refresh");

我得到以下信息: 错误:无法在初始化之前调用手风琴上的方法;试图调用方法“刷新”

当我检查应该刷新的 div 时,它具有以下 ids/classes:

DIV#shelf0sections.child-accordion.ui-accordion-content.ui-helper-reset.ui-...

我尝试使用选择器:

$('#shelf0sections .child-accordion').accordion("refresh"); 

相反,它不会给出错误,但视觉上没有任何反应。

jsFiddle:http://jsfiddle.net/Mw9SA/3/ (请注意,列表中的第一个元素只是查看嵌套手风琴工作的示例,如果您尝试向其中添加部分,它将不起作用。使用“+Shelf”按钮,然后打开新的手风琴并使用“+部分”按钮。)

【问题讨论】:

  • 嘿@b-en,您在代码中的哪个位置尝试调用$('.child-accordion').accordion("refresh"); 也许快速检查一下refresh 调用是否在var child = $(".child-accordion").accordion({...}); 位之前进行?跨度>
  • 嗨@Varinder,我确信该元素在我尝试刷新它之前就已经存在。例如,如果我在创建元素后输入控制台,我仍然会进入 $('.child-accordion').accordion("refresh"); 20:23:01.853 错误:无法在初始化之前调用手风琴上的方法;试图调用方法“刷新”而如果我调用以下方法,它可以正常工作:20:23:06.048 $('.child-accordion').fadeOut("slow");
  • 是否可以在jsfiddle.net 发一个快速的小提琴?
  • 这里:jsfiddle.net/Mw9SA/3,感谢您的浏览。
  • 另请注意,列表中的第一个元素只是查看嵌套手风琴工作的示例,如果您尝试向其中添加部分,它将无法正常工作。

标签: javascript jquery jquery-ui jquery-ui-accordion


【解决方案1】:

更模块化的方法怎么样?

小提琴或者它没有发生:http://jsfiddle.net/Varinder/24hsd/1/

说明

这个想法是(相同的)动态创建一个全新的手风琴元素,并在 DOM 中附加正确的事件。

将转发器HTML 标记抽象到 DOM 中某处的 template 并使用 JS 引用它而不是从字符串构建它通常更易于管理。

这是标记中的手风琴模板:

<div class="template">
    <div class="accordion">
        <h3 class="accordion-title">accordion title</h3>
        <div class="accordion-content">
            accordion content
        </div>
    </div>
</div>

这是完整的 HTML 标记 - 以防万一:

<div class="page">
</div>

<div id="addShelf" class="button">+ Shelf</div>
<div id="addSection" class="button">+ Section</div>

<div class="template">
    <div class="accordion">
        <h3 class="accordion-title">accordion title</h3>
        <div class="accordion-content">
            accordion content
        </div>
    </div>
</div>

JS

从存储不同的手风琴配置开始:

var shelfConfig = {
    collapsible: true, 
    autoHeight: false, 
    animated: "swing",
    heightStyle: "content"
}

var shelfSectionConfig = {
    active:false,
    collapsible: true, 
    autoHeight: false,
    animated: "swing"
}

跟踪当前手风琴编号和当前手风琴部分编号(最后一个手风琴内的部分数量) - 如果您需要移除手风琴架的功能,可能会派上用场

var currentShelfNumber = 0;
var currentShelfSectionNumber = 0;

Chaching DOM 元素,注意引用tempalte div

var $page = $(".page");
var $accordionTemplate = $(".template").children();

var $addSection = $("#addSection");
var $addShelf = $("#addShelf");

创建一个辅助函数,该函数简单地从 DOM 中返回手风琴模板的克隆副本

function getAccordionTemplate() {
     return $accordionTemplate.clone();   
}

主函数generateAccordion - 它有两个参数,accordionNumber 用于在标题等中附加当前数字,accordionType 用于找出要使用的手风琴配置。

使用这些参数,它将返回一个全新的手风琴,并附加适当的事件,然后可以将其附加到 DOM

function generateAccordion( number, accordionType ) {
    var $accordion = getAccordionTemplate();
    var accordionTitle = "twerking bieber?";

    if ( accordionType == "shelf" ) {
        accordionTitle = "Shelf " + number;    
    } else {
         accordionTitle = "Shelf Section";
    }

    $accordion.find("h3").text( accordionTitle );

    var $accordionWithEvents = attachAccordionEvents( $accordion, accordionType );

    return $accordionWithEvents;
}

注意对另一个函数 attachAccordionEvents 的调用,顾名思义 - 这个家伙会将事件附加到手风琴元素。

function attachAccordionEvents( $accordionElement, accordionType ) {
    if ( accordionType == "shelf" ) {
        $accordionElement.accordion( shelfConfig );
    } else {
        $accordionElement.accordion( shelfSectionConfig );    
    }

    return $accordionElement;
}

另一个帮助功能确保“添加部分”按钮在没有手风琴架可以工作时不会显示

function manageSectionButton() {
    if ( $page.children().length > 0 ) {
        $addSection.show();
    } else {
        $addSection.hide();
    }
}

最后的事件和逻辑:

$addShelf.on("click", function(e) {
    e.preventDefault();

    var newShelfNumber = currentShelfNumber + 1;
    var $shelfElement = generateAccordion( newShelfNumber, "shelf" );

    currentShelfNumber = newShelfNumber;

    $page.append( $shelfElement );


    manageSectionButton();
});

$addSection.on("click", function(e) {
    e.preventDefault();

    var newShelfSectionNumber = currentShelfSectionNumber + 1;
    var $shelfSectionElement = generateAccordion( newShelfSectionNumber, "section" );
    var $activeShelfElement = $page.children().last().find(".accordion-content");

    $activeShelfElement.append( $shelfSectionElement );
});

...仅此而已。

希望这会有所帮助,

干杯

【讨论】:

  • 哇,这太棒了!非常感谢你的帮助。您可能会说,我是 Web 开发的新手,所以我非常感谢您的彻底回答和解释!一旦我重构我的代码,我会报告。再次感谢您!
  • 我浏览了我的代码并最终使用了很多您建议的内容。唯一的区别是我希望所有元素都属于同一个手风琴,这样我就可以使用 .accordion("option", "active") 以及一次只强制打开一个。为此,我从模板中删除了外部 div,以便只应用手风琴 h3 和 div。再次感谢,你真的帮助了我,我的代码现在更有意义了。
猜你喜欢
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 2015-02-17
  • 2014-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多