我正在尝试克隆一个bootstrap元素,它具有bootstrap提供的数据切换行为:
HTML
<div class="container">
<button aria-expanded="false" data-target="#collapsible_obj_0" data-toggle="collapse" class="btn btn-link collapsed">click here</button>
<div style="height: 0px;" aria-expanded="false" id="collapsible_obj_0" class="collapse">
<span>foo</span>
</div>
</div>
克隆后,我正在改变 ID
的 DIV 一个新的独特的id,和 data-target
按钮指向 新的div。
JS
var header = objectContainer.clone(true);
var counter = this.collapsibleObjCounter++;
var collapseId = "collapsible_obj_" + counter;
header.find(".collapse").attr("id", collapseId);
header.find("button[data-toggle='collapse']").attr("data-target", "#"+collapseId);
按钮和div是我对象容器的子项 克隆。
有时它可以工作,但有时我最终会得到一个仍然扩展和收缩原始div的按钮,即使我检查HTML时,ID看起来是正确的。
我怀疑复制的事件处理程序可能是硬编码对要扩展和收缩的div的id的引用,这就是为什么只修复DOM元素中的ID不起作用的原因。但是,这并不能解释为什么有些克隆工作而其他克隆无效。
克隆附加了引导行为的东西的正确方法是什么?
所以,有几个答案指出只是删除 true
从我的 clone()
调用将避免复制事件监听器。所以我现在意识到我的问题比我在这里过于简化的问题要复杂一些。我会把它作为一个单独的问题。 (克隆Bootstrap元素但不是所有事件侦听器)
到目前为止你的代码还可以,只需删除即可 true
从 clone()
它不需要。
更新
这个 布尔 value指示是否应将事件处理程序与元素一起复制。默认值是 假 。所以,当我们打电话给 .clone()
方法没有通过任何 布尔 值,它只是复制元素而不是复制 事件处理程序 附在它上面。但是,当我们传递价值时 真正 ,它复制了元素和任何元素 事件处理程序 附在它上面。
但 引导 正在处理 事件处理程序 对于动态对象,所以你不需要 true
在克隆中。
喜欢
如果你正在处理 events
对于使用这种方式的动态对象
$(".btn").click(.....);
// This button was dynamically created and you want a click event for it,
// but it wont work because at the time of event binding this button wasn't exist at all.
但
你需要处理 事件 用于动态对象 事件授权 技术。
$(document).on("click",".btn",function(){ .... });
这将起作用,因为事件处理程序绑定到更高的元素 DOM
树(在这种情况下,文档)并将在事件到达源自与选择器匹配的元素的元素时执行,
那是什么 引导 对于动态对象,如果动态对象需要,也会这样做。她是 的jsfiddle 为了这。
你还需要包裹整个 collapsible
参与 div
用于克隆。
注意: 运用 .clone()
具有产生重复元素的副作用 id
属性,应该是唯一的。在可能的情况下,建议避免使用此属性克隆元素或使用类属性作为标识符。
所以,你需要更新 data-target
和 div
ID 克隆后的属性,使新创建的按钮 targets
新创建的折叠面板
我在用 jQuery的 为了它。
这是代码 片段
$(function(){
var target = "collapsible_obj_";
var i = 1;
$("#button").click(function(){
$(".parent_colapse:last").clone().insertAfter(".parent_colapse:last");
$(".parent_colapse:last > button").attr("data-target", "#"+target+i);
$(".parent_colapse:last .collapse").attr("id", target+i);
i++;
});
$(document).on("click",".button",function(){
alert();
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="parent_colapse">
<button aria-expanded="false" data-target="#collapsible_obj_0" data-toggle="collapse" class="btn btn-link collapsed">click here</button>
<div style="height: 0px;" aria-expanded="false" id="collapsible_obj_0" class="collapse">
<span>foo</span>
<button type="button" class="button">click</button>
</div>
</div>
<button type="button" id="button">Clone</button>
关于 你的问题,你没有充分展示 script
这就是我们无法找到错误的原因。 喜欢 我们不知道 objectContainer
也不 collapsibleObjCounter
那是什么?
克隆时不要复制事件,删除 true
旗。
var header = objectContainer.clone();
我的猜测是Bootstrap正在处理动态对象的事件绑定,也用于数据切换,它只需要具有不同的id和目标。
这是一个 小提琴。
PS:不知道在OP的问题中这个或objectContainer是什么,所以在新的包装器中创建了一个闭包和粘贴结果。
我已经创建了一个代码的JSFiddle。最可能的错误似乎是你在哪里使用 this.collapsibleObjCounter++
的价值 0
这可能会造成一个问题。
这是一个有效的JSFiddle。如果您正在尝试这样做,请告诉我。谢谢。
https://jsfiddle.net/2fgoywzy/1/
JS
$( document ).ready(function() {
for (i = 1; i < 5; i++) {
var objectContainer = $("#main");
var header = objectContainer.clone(true);
var counter = i; // replace this with this.collapsibleObjCounter++
var collapseId = "collapsible_obj_" + counter;
header.find(".collapse").attr("id", collapseId);
header.find("button[data-toggle='collapse']").attr("data-target", "#"+collapseId);
$(header).appendTo('body');
}
});
HTML
<div id="main">
<button aria-expanded="false" data-target="#collapsible_obj_0" data-toggle="collapse" class="btn btn-link collapsed">click here</button>
<div style="height: 0px;" aria-expanded="false" id="collapsible_obj_0" class="collapse">
<span>foo</span>
</div>
</div>
如果你的价值是 0
在 this.collapsibleObjCounter++
那我建议做 ++this.collapsibleObjCounter
。代替 后增量 做 预增量
问题不是由事件侦听器引起的 在他们自己。问题是Bootstrap的工作原理。对于大多数Bootstrap组件,Bootstrap创建与DOM元素关联的JavaScript对象。 克隆Bootstrap组件时需要注意此对象。 为一个 collapse
元素,Bootstrap创建一个 Collapse
目的。
JavaScript对象通过jQuery与DOM元素相关联 $.data
。 这个 是问题。如果你使用jQuery clone
并请求将事件处理程序复制到克隆,然后您还可以获得数据集的副本 $.data
。但是,当数据是对JavaScript对象的引用时,它就是 参考 复制到克隆。所以原始和克隆引用相同的JavaScript对象,这就是一切都误入歧途的地方。顺便说一下,这对Bootstrap来说并不特殊:任何引用都会遇到这个问题。
你能做的就是表演一个 $.removeData
在作为Bootstrap组件的克隆元素上。这将强制Bootstrap重新创建JavaScript对象。对于自动注册数据API的组件,这应该是所需的全部内容。 (collapse
自动注册。)对于那些做的组件 不 自动注册(例如工具提示),您需要致电 $.[component]
手动重新创建组件。
我有 分叉小提琴 从 aManHasNoName说明这一点的小提琴。唯一的修改是:
添加参数 true, true
至 var header = objectContainer.clone();
修改 header.find(".collapse").attr("id", collapseId)
加上 .removeData()
最后。