如果元素在 <form> 内,为啥 clone() 太慢?
Posted
技术标签:
【中文标题】如果元素在 <form> 内,为啥 clone() 太慢?【英文标题】:Why the clone() is too slow if the elements are inside a <form>?如果元素在 <form> 内,为什么 clone() 太慢? 【发布时间】:2011-11-05 12:03:18 【问题描述】:Here 你可以找到整个例子。
通过点击点击添加,您将克隆 100 次元素 trackOn
;然后它将附加到表tracklistOn
。
不幸的是,如果这些元素在 form
内,您会看到该过程完成之前的时间非常长。 如果我删除表格,是非常直接的。为什么会出现这种行为?
完整的代码在这里:
html
<div style="cursor:pointer;" id="addTr">Click to Add</div>
<form action="index.php?status=add" method="POST">
<table class="tracklistOn" cellpadding="0" cellspacing="0"></table>
<table class="tracklistOff" style="display:none;">
<tr class="trackOn">
<td class="trackTime">
<select class="trackTimeHH" name="hours[]">
<option>??</option><option value="">-</option><option value="00">00</option> <option value="01">01</option> <option value="02">02</option> <option value="03">03</option> <option value="04">04</option> <option value="05">05</option> <option value="06">06</option> <option value="07">07</option> <option value="08">08</option> <option value="09">09</option> <option value="10">10</option> <option value="11">11</option> <option value="12">12</option> <option value="13">13</option> <option value="14">14</option> <option value="15">15</option> <option value="16">16</option> <option value="17">17</option> <option value="18">18</option> <option value="19">19</option> <option value="20">20</option> <option value="21">21</option> <option value="22">22</option> <option value="23">23</option> <option value="24">24</option> <option value="25">25</option> <option value="26">26</option> <option value="27">27</option> <option value="28">28</option> <option value="29">29</option> <option value="30">30</option> <option value="31">31</option> <option value="32">32</option> <option value="33">33</option> <option value="34">34</option> <option value="35">35</option> <option value="36">36</option> <option value="37">37</option> <option value="38">38</option> <option value="39">39</option> <option value="40">40</option> <option value="41">41</option> <option value="42">42</option> <option value="43">43</option> <option value="44">44</option> <option value="45">45</option> <option value="46">46</option> <option value="47">47</option> <option value="48">48</option> <option value="49">49</option> <option value="50">50</option> <option value="51">51</option> <option value="52">52</option> <option value="53">53</option> <option value="54">54</option> <option value="55">55</option> <option value="56">56</option> <option value="57">57</option> <option value="58">58</option> <option value="59">59</option>
</select>
</td>
<td class="trackTime">
<select class="trackTimeMM" name="minuts[]">
<option>??</option><option value="">-</option><option value="00">00</option> <option value="01">01</option> <option value="02">02</option> <option value="03">03</option> <option value="04">04</option> <option value="05">05</option> <option value="06">06</option> <option value="07">07</option> <option value="08">08</option> <option value="09">09</option> <option value="10">10</option> <option value="11">11</option> <option value="12">12</option> <option value="13">13</option> <option value="14">14</option> <option value="15">15</option> <option value="16">16</option> <option value="17">17</option> <option value="18">18</option> <option value="19">19</option> <option value="20">20</option> <option value="21">21</option> <option value="22">22</option> <option value="23">23</option> <option value="24">24</option> <option value="25">25</option> <option value="26">26</option> <option value="27">27</option> <option value="28">28</option> <option value="29">29</option> <option value="30">30</option> <option value="31">31</option> <option value="32">32</option> <option value="33">33</option> <option value="34">34</option> <option value="35">35</option> <option value="36">36</option> <option value="37">37</option> <option value="38">38</option> <option value="39">39</option> <option value="40">40</option> <option value="41">41</option> <option value="42">42</option> <option value="43">43</option> <option value="44">44</option> <option value="45">45</option> <option value="46">46</option> <option value="47">47</option> <option value="48">48</option> <option value="49">49</option> <option value="50">50</option> <option value="51">51</option> <option value="52">52</option> <option value="53">53</option> <option value="54">54</option> <option value="55">55</option> <option value="56">56</option> <option value="57">57</option> <option value="58">58</option> <option value="59">59</option>
</select>
</td>
<td class="trackTime">
<select class="trackTimeSS" name="seconds[]">
<option>??</option><option value="">-</option><option value="00">00</option> <option value="01">01</option> <option value="02">02</option> <option value="03">03</option> <option value="04">04</option> <option value="05">05</option> <option value="06">06</option> <option value="07">07</option> <option value="08">08</option> <option value="09">09</option> <option value="10">10</option> <option value="11">11</option> <option value="12">12</option> <option value="13">13</option> <option value="14">14</option> <option value="15">15</option> <option value="16">16</option> <option value="17">17</option> <option value="18">18</option> <option value="19">19</option> <option value="20">20</option> <option value="21">21</option> <option value="22">22</option> <option value="23">23</option> <option value="24">24</option> <option value="25">25</option> <option value="26">26</option> <option value="27">27</option> <option value="28">28</option> <option value="29">29</option> <option value="30">30</option> <option value="31">31</option> <option value="32">32</option> <option value="33">33</option> <option value="34">34</option> <option value="35">35</option> <option value="36">36</option> <option value="37">37</option> <option value="38">38</option> <option value="39">39</option> <option value="40">40</option> <option value="41">41</option> <option value="42">42</option> <option value="43">43</option> <option value="44">44</option> <option value="45">45</option> <option value="46">46</option> <option value="47">47</option> <option value="48">48</option> <option value="49">49</option> <option value="50">50</option> <option value="51">51</option> <option value="52">52</option> <option value="53">53</option> <option value="54">54</option> <option value="55">55</option> <option value="56">56</option> <option value="57">57</option> <option value="58">58</option> <option value="59">59</option>
</select>
</td>
</tr>
</table>
</form>
jQuery
$('#addTr').click(function ()
var savedTrackOn=$('.tracklistOff').find('.trackOn');
for(i=0; i<100; i++)
savedTrackOn.clone().appendTo($('.tracklistOn'));
);
我该如何解决这个问题?
编辑
在 Firefox 6.0 上试过,问题消失了:O 只有旧版本和 chrome+IE?为什么?
【问题讨论】:
这是一个很好的问题。我发现性能因浏览器而异,但模式保持不变。在旁注中,我认为一个界面希望我通过使用 3 个不同的单独下拉菜单来选择 100 次,我会很快放弃。可能还有另一种方法可以完全做到这一点。但我还是想知道是什么原因造成的。 是的。事实上,“复制”的代码并没有那么大……但性能确实很慢。希望有人可以帮助我们:) 非常有趣。我尝试了一些不同的方法(即使用纯 JS/DOM 代替 jQuery;下拉列表中没有名称属性;将模板放在表单之外;使用 div 代替表格;使用 innerHTML 而不是.clone()
或@“克隆” 987654328@; 使用createElement()
“手动”构建新行;等等)但没有任何帮助。只要它在表单元素中,它就会很慢。再次:有趣
【参考方案1】:
The documentation 明确声明如下:
.clone() 方法执行匹配集的深层复制 元素,这意味着它复制匹配的元素以及所有 它们的后代元素和文本节点。配合使用时 使用其中一种插入方法, .clone() 是一种方便的方法 页面上的重复元素
知道了这一点,明智的做法是限制.clone()
的预期深度遍历量。
这个问题与 jQuery 完全无关,如 here 所示,我已经用主机 API 代码替换了您的代码,并且感知到的性能问题仍然存在。
最后,我能够确定另一个解决此问题的“解决方法”,这使我们相信问题还在于附加新节点take a look,您会看到移动目标元素 out 的形式也大大提高了性能。
【讨论】:
我认为您可以轻松删除表单元素并使用 javascript 创建行为。少量重构可以轻松解决您的性能问题。【参考方案2】:这只是为了充实我之前的评论,并附和 Rick 所说的内容。
我尝试了以下方法(在 Safari 中):
使用纯 javascript(无 jQuery):仍然很慢 使用 div 代替表格:仍然很慢 使用innerHTML
代替.clone()
/cloneNode()
:还是很慢
将模板移出表单:仍然很慢
从头开始构建元素而不是克隆:仍然很慢
将所有内容附加到表单外的临时元素,然后移动它:仍然很慢
在添加元素时隐藏表单:还是很慢
在克隆/复制/其他之前删除输入元素上的名称属性:仍然很慢
删除表单本身的属性:仍然很慢
使用普通编号而不是列表式命名(即“nameX”而不是“name[]”):仍然很慢
同样,只要您将这些 select
输入附加到表单元素,它就会很慢。
但正如 Rick 所建议的,您可以将输入附加到表单之外的元素,并使用 JS 序列化并提交它们。
或者,您可以将input type="hidden"
元素附加到表单(速度很快)到表单,同时将实际的select
元素附加到表单之外的内容。然后您可以想象使用事件侦听器使隐藏的输入反映选择的值。隐藏的输入将与表单一起提交,而选择仅用作用户界面。
另一种选择是让标记中的下拉菜单开始(我怀疑浏览器会快速呈现),但让它们被禁用和隐藏。然后在需要时使用 javascript 取消隐藏并启用下拉菜单。我不知道这是否也会导致速度变慢,但由于没有添加新元素,它应该会更快。
仍然没有解释缓慢(或者为什么它在 FF6 中显然很快)
【讨论】:
“那么您可以想象使用事件侦听器来使隐藏的输入反映选择的值”:哦……这是一个不错的策略!说实话没想到 :) 是啊,那个慢很奇怪...没人给我解释... 不幸的是,我在表单上输入了许多其他内容,并且我对其进行了动态编辑。我认为唯一的方法是在将项目发送到服务器之前对其进行序列化......(使用 jquery 这将更容易和更快......)以上是关于如果元素在 <form> 内,为啥 clone() 太慢?的主要内容,如果未能解决你的问题,请参考以下文章