在开发ns-log项目中,统计分类有复制的功能。由于之前的统计分类中的数据是通过JS赋值进去的,之后用户可能又进行了修改,发现进行节点克隆时,出现了 无法复制select下拉框值的怪异现象。本文对这个怪异现象进行解析和给出解决办法。
问题现状
使用节点的cloneNode(true/false)进行克隆时,目前是下面的表现情况:
- select为设置初始值或者初始值是第一个option。 表现:各大浏览器都没什么问题。
- select初始值不是在第一个option。 表现:IE下无法克隆,其他内核的浏览器没什么问题。
- select的值被用户或者JS修改。 表现:各个浏览器均无法克隆到真确的值。值结果跟第二条结果相同。
IE的特殊处理
对于上面第二条,初始值不在第一个option时无法克隆的情况,确实是IE的一个Bug,相信不少人都遇到过这样的问题。并且IE下使用cloneNode方法时,还有Event方面的问题,所以差不多可以放弃使用这个方法。
IE下可以使用节点的outerHTML属性解决这个问题,它能够实时的获取节点的内容,哪怕是select的值被用户或者程序改变。下面给出简单的实现。
function clone(node) {
var div = document.createElement('div');
div.innerHTML = node.outerHTML;
return div.childNodes[0];
}
其他内核浏览器的处理
既然IE内核的浏览器可以通过outerHTML属性来解决这个问题,那FF等浏览器可以通过类似的方法来实现吗?虽然FF等浏览器没有outerHTML属性,但是可以通过innerHTML属性实现,如:
function getOuterHTML(node) {
var div = document.createElement('div');
div.appendChild(node);
try {
return div.innerHTML;
} catch (e) {
div = null;
}
}
答案是否定。
为什么会这样呢?难道是FF等浏览器的bug?
下面还是从W3C中对cloneNode方法,select标签,属性的定义进行说明。
下面引用的资料都是来自HTML5草案,HTML4或者XHTML对这些没有太多详细的定义。虽然是HTML5的,但这些节点跟以前没什么变化。
W3C中的cloneNode
具体链接:http://www.w3.org/TR/DOM-Level-2-Core/core.html
里面有2点比较重要:
- 克隆时会拷贝节点的所有属性和对应的值。
- 如果cloneNode方法的参数为true,会通过递归的方法克隆子节点。
W3C中的select节点
具体链接:http://dev.w3.org/html5/spec/forms.html#the-select-element
W3C对于属性的定义有2种,一种是内容性属性(Content attributes),另一种是操作性属性(未给出具体的命名,这里暂时使用这个名字)。
对于select标签,内容性属性主要有:Global attributes,autofocus,disabled,form,multiple,name,size。其中Global attributes包含一些常用的属性(accesskey,class,contenteditable,contextmenu,dir,draggable,hidden,id,itemid, itemprop,itemref,itemscope,itemtype,lang,spellcheck,style,tabindex,title),这些属性是所有标签里都包含的,具体的见http://dev.w3.org/html5/spec/dom.html#global-attributes
而selectedIndex和value都属于操作性属性,这两个属性获取值的方式如下:
select . selectedIndex[ = value ] Returns the index of the first selected item, if any, or −1 if there is no selected item. Can be set, to change the selection. select . value [ = value ] Returns the value of the first selected item, if any, or the empty string if there is no selected item. Can be set, to change the selection.
内容性属性和操作性属性的区别
给节点添加属性有两种方式,如下面所示:
var div = document.createElement('div')
div.id = 'welefen'; //直接加属性
div.setAttribute('id','welefen'); //通过setAttribute方法添加属性
对于内容性属性,这两种方法是完全相同的。
但对于操作性属性,第一种方式只会将属性添加在操作范围内,当把节点添加到DOM中,属性就失效了。
由于selectedIndex和value都是操作性属性,如果select的值被用户或者程序改变,clone时当前的值是无法带过去的。所以才会出现了无法克隆值的情况。并且也无法使用innerHTML来克隆值,因为innerHTML的原理跟这个是一样的。
innerHTML实现原理请看这里:
FF等浏览器解决方案
目前有2中解决方案,第一种是在select绑定change事件,触发change的时候,改变options里的selected属性,当然这种方法是很不可取的。另一种方案就是在克隆时获取元素的值,然后再赋值到克隆后的对象上去。
总结
当前出现这个情况的时候,以为是FF等浏览器的bug。当后来仔细想想,应该不会这样的情况,后来反复查看W3C相关的文档,终于确认了这一问题。下面给出完整的解决方案:
function cloneSelect(select) {
if (document.all) {
var html = select.outerHTML,
div = document.createElement('div');
div.innerHTML = html;
return div.childNodes[0];
}
var cloneSelect = select.cloneNode(true);
cloneSelect.selectedIndex = select.selectedIndex;
cloneSelect.value = select.value;
return cloneSelect;
}
相关推荐
Java中的clone方法详解_动力节点Java学院,动力节点口口相传的Java黄埔军校
使用TreeNode的`Clone()`方法可以创建一个与原始节点完全相同的副本。然后,根据需要选择添加副本的位置,可能是同一层级或者作为其他节点的子节点。同时,如果需要保存复制节点的数据,需在数据库中进行相应的复制...
测试发现,textarea和select的jquery的clone方法有问题,textarea和select的值clone的时候会丢掉,发现这个是jquery的一个bug,上不了的可以看下代码,比较简单。就是在clone的时候将val再重新赋值一下,如果知道这个...
Java中的`clone`方法是Java语言提供的一种复制对象的方式,它允许创建一个对象的副本,这个副本与原对象具有相同的属性值,但它们是两个独立的对象,修改副本不会影响原对象。`clone`方法存在于Java的`java.lang....
在Java编程语言中,`clone()`方法是一个非常重要的概念,特别是在处理对象复制和克隆时。这个方法源自`Object`类,是所有Java类的基类。`clone()`的使用通常涉及到深度复制和浅复制的概念,这两者在数据结构和内存...
在Java编程语言中,`clone`是一个非常重要的概念,它涉及到对象复制和对象克隆。本文将深入探讨Java中的`clone`方法,包括其工作原理、使用场景、注意事项以及一些个人实践心得。 首先,让我们理解什么是`clone`。...
`jlink v9 warning clone`问题通常涉及到JLink版本9在与MDK配合使用时遇到的警告,提示可能与克隆设备或非法设备相关。 标题中的"jlink v9 warning clone解决"意味着开发者正在尝试解决关于JLink v9版本出现的克隆...
Java中的`clone()`方法是Object类的一个成员方法,它提供了创建一个对象副本的功能。这篇文章将深入探讨`clone()`方法的工作原理、使用场景以及浅拷贝(shallow clone)与深拷贝(deep clone)的区别。 首先,让...
Java中的clone方法详解 在Java语言中,clone方法是一个非常重要的概念,它允许对象被复制,从而创造出一个新的对象。下面我们将详细介绍Java中的clone方法,并讨论它的实现机制和应用场景。 什么是clone方法 ...
当遇到"Jlink-clone"问题时,这通常指的是遇到了非原厂生产的、可能功能受限或者不稳定版本的J-Link设备。这类克隆设备可能会有兼容性问题、性能下降或不支持某些高级功能。本文将深入探讨如何解决Jlink-clone带来的...
Java中的克隆(Clone)机制是一种创建对象副本的方法,它允许程序员复制一个对象的状态,而不会影响原始对象。克隆在编程中常用于创建对象的独立副本,使得新副本与原对象之间相互独立,对其中一个对象的修改不会...
本篇文章将深入探讨“JQ创建节点”的知识点,这在构建动态网页时非常关键。 首先,理解DOM(Document Object Model)是至关重要的。DOM是HTML或XML文档的结构化表示,允许程序和脚本动态更新、添加或删除页面元素。...
JQuery库中的clone方法是其强大的功能之一,它允许开发者复制文档中的元素节点,进而可以将这些副本插入到DOM的其他位置或进行其他操作。在本知识点中,我们将详细介绍JQuery中clone方法复制节点的使用方法,重点...
在使用高版本版KEIL时,提示要升级固件,升级后就出现JLINK is Clone的提示!“the emulator is JLink-Clone, the segger software only support orginal segger device” 然后闪退,IDE崩溃关闭! 解决方案: 1....
Minesweeper CLone 0.97 Saolei.net扫雷网,小门汉化 Men Shiyun Mine.exe 请自行下载MinesweeperClone_0.97.exe安装后使用
jquery.clone
TreeNode newNode = copiedNode.Clone() as TreeNode; // 克隆节点 newNode.Text = "粘贴的节点"; insertParent.Nodes.Add(newNode); treeView1.ExpandAll(); } } ``` 在上述代码中,我们只涉及了基本的逻辑。...
详细的描述了Java中 clone方法使用
这里,`find('option')`找到`select1`下的所有`<option>`,然后`each()`遍历每个选项,`clone()`复制选项,最后`append()`将复制的选项添加到`select2`。 对于单选操作,我们可以监听`change`事件,当用户更改选项...