如何替换具有自定义元素的JQuery UI小部件

时间:2015-04-02 07:30:02

标签: jquery jquery-ui

我已经获得了附加DOM元素的JQuery UI小部件来完成这项工作。小部件在_destroy方法中删除了这个元素,因此它将自行清理。

在尝试用其他小部件替换小部件之前,一切都很好。原始窗口小部件被删除(destroy方法将删除窗口小部件自定义元素),但不会附加新窗口小部件。

最佳描述是代码,因此这里是示例:http://jsfiddle.net/71xdxLvp/3/

问题是: 如何更换我的小部件?

注意:

我知道问题出在哪里,但我不知道如何解决问题。

问题出在方法replaceWith的jquery.js中 - 请参阅代码中的注释:

return this.each(function() {
    var next = this.nextSibling, // nextSibling is widgets custom element
    parent = this.parentNode;

    // Widget is removed and the widgets custom element is removed too
    jQuery( this ).remove();

    if ( next ) {
        // New widget should be prepended to the widgets custom element, but  
        // the element is already removed from DOM. 
        // Method before() check this and won't append new widget
        jQuery(next).before( value );
    } else {
        jQuery(parent).append( value );
    }
});

修改

replaceWith由第三方框架Apache Wicket

调用 创建DOM元素的

小部件是CodeMirror

1 个答案:

答案 0 :(得分:1)

你偶然发现了一个带有.replaceWith()的晦涩的角落案例,导致了一个错误。会发生什么:

  • 通过销毁第一个节点,你自己也会销毁以下兄弟
  • .replaceWith调用destroy函数,然后尝试在现在不存在的兄弟之前插入一个新节点
  • 在丢失的节点上抛出NotFoundError

如果您“模拟”replaceWith自己做的事情,您可以相当简单地解决这个问题:首先附加新元素,然后才调用remove

$("#widget").next().before("<div id=\"secondWidget\"></div>");
$("#widget").remove();

小提琴:http://jsfiddle.net/w7Lqfzcc/1/


如果这不是一个选项(如评论中所述),您可以做一些稍微不同的事情:不要直接调用.remove,只需添加一个display:none的类,然后再清理它:

this.widgetContent.addClass("inactive");

.widgetContent.inactive { display:none; }

小提琴:http://jsfiddle.net/w7Lqfzcc/3/ [注意我用小提琴中的一个类替换了id;使用id-s生成子元素没有多大意义]

这很麻烦,但这是解决你所拥有的笨拙的widget-generated-sibling结构的最简单方法。如果您想要清理它,首先应该使用某种小部件级容器。