首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >克隆和恢复“工具提示”元素

克隆和恢复“工具提示”元素
EN

Stack Overflow用户
提问于 2015-04-07 12:31:32
回答 3查看 2.2K关注 0票数 9

我在恢复DOM结构时遇到了麻烦,DOM结构中的元素被传递给Bootstrap的.fn.tooltip()方法。

具体而言:$('footer p')被传递给document的工具提示,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
$(function(){

$('footer p').tooltip();
$('footer p').on('click', function(){
console.log('Just to test events')
});

})

我检查它,工具提示工作,点击控制台消息出现。现在,通过调用函数,从控制台备份将要删除和删除的内容:

代码语言:javascript
代码运行次数:0
运行
复制
function experiment_destroy() {
window.backup = $('footer').clone(true, true);
$('footer p').remove();
}

正如所料,页脚的p消失了。

现在,我使用以下方法还原在window.backup变量中克隆和缓存的内容:

代码语言:javascript
代码运行次数:0
运行
复制
function experiment_restore(){
    $('footer').empty();
    $('footer').replaceWith(window.backup);
}

也是从控制台调用的,下面是发生的情况:

  • footer p元素以应有的方式返回。
  • 单击footer p生成控制台消息“只用于测试事件”消息,因此该事件与元素一起还原。
  • 没有工具提示被还原为

即使我在函数experiment_restore中重新调用工具提示方法,我也什么也得不到。有人有什么想法吗?

更新:,我又做了一个变体。尝试使用不同的-完全最小的DOM环境,只对p进行tooltip和父容器元素。结果是相同的。当然,在我复杂的DOM结构中,不只是一些东西把事情搞砸了。

这是非常简单的Fiddle

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-10 11:48:59

对于您在问题中显示的场景,我将使用$().detach()从DOM中删除它,同时保持事件处理程序和添加到DOM的数据与$().data()保持完整。关于你所提出的问题:

代码语言:javascript
代码运行次数:0
运行
复制
$('#destroy').click(function(){
    var $footer_p = $('footer p');
    window.backup = $footer_p;
    $footer_p.detach();
})

$('#restore').click(function(){
    var $footer = $('footer');
    $footer.append(window.backup);
});

这里有一个更新的小提琴

幕后发生的事情是,Bootstrap使用$().data()将类Tooltip的JavaScript对象添加到DOM元素中,并添加了一组事件处理程序。你需要保存这些。

如果由于某种原因不能使用$().detach(),则必须通过调用$().tooltip()重新创建工具提示。

为什么$().clone(true, true)不能工作?

您使用参数调用$().clone()来深入克隆DOM层次结构,并使用$().data()保留事件处理程序和数据集,那么为什么它不能工作呢?克隆不是应该有一个引用的Tooltip对象创建的引导吗?

是的,事件处理程序被保留下来,并且克隆确实有一个对Tooltip对象的引用。但是,这个对象本身并不是克隆出来的。更重要的是,它不适合引用$().clone()创建的新DOM节点。(因此,即使jQuery克隆了它,它仍然不能工作。)它确实收到了触发工具提示的事件,但是Tooltip.prototype.show执行以下检查:

代码语言:javascript
代码运行次数:0
运行
复制
  var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
  if (e.isDefaultPrevented() || !inDom) return

如果inDom在DOM中,则this.$element变量将为真。但是,这是指为其创建工具提示的原始元素,而不是克隆。由于该元素已不在DOM中,所以inDom为false,下一行将返回,因此工具提示永远不会显示。

对于咯咯笑,使用创建引导工具提示的DOM元素的克隆,不要删除原始元素,而是将克隆添加到页面的其他地方。然后触发克隆上的工具提示。工具提示将出现在原始元素上。:)

我上面描述的是Bootstrap的jQuery插件的一般工作方式:他们使用$().data()将JavaScript对象添加到它们操作的元素中。还有一个用于下拉的Dropdown类,一个用于modals的Modal类,等等。

票数 3
EN

Stack Overflow用户

发布于 2015-04-09 12:55:50

您需要再次调用tooltip()方法。或者,在克隆/删除用于清理数据的项之前,应该销毁工具提示。

工频

代码语言:javascript
代码运行次数:0
运行
复制
$('footer p').tooltip();

$('#destroy').click(function(){
    // optionally remove bindings
    $('footer p').tooltip('destroy');

    window.backup = $('footer').clone();
    $('footer p').remove();
})

$('#restore').click(function(){
    $('footer').replaceWith(window.backup);

    // apply tooltip again
    //window.backup.find("p").tooltip();
    $('footer p').tooltip();
});
票数 7
EN

Stack Overflow用户

发布于 2020-12-06 20:52:56

作为一个补充答案,我使用了JQuery的克隆方法,但是我复制了所有的事件侦听器,比如.clone(true, true)。我的问题是,工具提示与旧元素和克隆元素完全相同,但它们位于不同的位置(因此,在新元素上盘旋会在浏览器的左上角显示工具提示)。

我能想到的最简单的修复方法应该适用于所有Javascript,Bootstrap,JQuery,永远是:

代码语言:javascript
代码运行次数:0
运行
复制
const target = document.getElementById("random-div-you-want-to-clone-to")
$("selecting").clone(true, true).appendTo(target);

// if you only want .innerHTML of $("selecting")
// you can do $("selecting").children()

const _tooltips = target.querySelectorAll("[data-toggle='tooltip']");
for (const x of _tooltips) {
    const build = x.cloneNode(true);
    $(build).tooltip();
    x.parentNode.replaceNode(build, x);
}

因此,.clone(true, true)将抓取所有事件侦听器,包括"mousedown“,即工具提示的侦听器。当您使用本机ECMAScript的cloneNode方法时,您不会获得事件侦听器,因此需要重置工具提示。

这不是最有效率的,但我花了一个小时努力想些什么.作为我的客人,在寻找一个更有效的方法,因为这个方法不是,但它的工作。(例如使用forEach,直接使用JQuery等等)。

编辑:您还可以在克隆时使用.children()获取$("selecting")的内部(即其子),而不是获取它和其子节点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29491673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档