2015-04-02 47 views
2

我有JQuery UI小部件附加了DOM元素来完成这项工作。这个小部件在_destroy方法中删除了这个元素,所以它会自行清理。如何替换具有自定义元素的JQuery UI小部件

一切都很好,直到我尝试用一​​些其他小部件替换小部件。原始小部件被删除(销毁方法将删除小部件自定义元素),但新的小部件不附加。

最好的说明是代码,所以这里是例子: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

你已经偶然发现了一个晦涩的角落案例.replaceWith(),这导致了一个bug。什么情况是:

  • 摧毁的第一个节点,你也破坏了以下同级自己
  • .replaceWith调用,销毁功能,然后尝试,现在不存在兄弟
  • 它抛出之前插入一个新节点丢失节点上的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生成的兄弟结构的最简单方法。如果你想清理它,使用某种小部件级别的容器是你首先应该考虑的事情。

+0

不幸的是'.replaceWith'被第三方库(Wicket)调用,所以我不能自己模拟它。 :( – 2015-04-02 14:02:37

+0

我看到了;检查编辑是否有帮助,我通常会推荐阅读你的小部件的结构,因为replaceWith可能不是依赖兄弟的唯一函数 – blgt 2015-04-02 14:30:03

+1

感谢您的更新 - 这是一个混乱的方式,但我认为它可以工作,Widget也是第三方(见我的编辑),所以我不能轻易修改它的结构。 – 2015-04-08 08:30:42

相关问题