我正在尝试克隆一个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() 最后。