`
k1121
  • 浏览: 181077 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

select节点clone全解析

 
阅读更多

在开发ns-log项目中,统计分类有复制的功能。由于之前的统计分类中的数据是通过JS赋值进去的,之后用户可能又进行了修改,发现进行节点克隆时,出现了 无法复制select下拉框值的怪异现象。本文对这个怪异现象进行解析和给出解决办法。

问题现状

使用节点的cloneNode(true/false)进行克隆时,目前是下面的表现情况:

  1. select为设置初始值或者初始值是第一个option。 表现:各大浏览器都没什么问题。
  2. select初始值不是在第一个option。 表现:IE下无法克隆,其他内核的浏览器没什么问题。
  3. 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点比较重要:

  1. 克隆时会拷贝节点的所有属性和对应的值。
  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;
}

原文链接:http://www.welefen.com/select-clone.html

分享到:
评论

相关推荐

    Java中的clone方法详解_动力节点Java学院

    Java中的clone方法详解_动力节点Java学院,动力节点口口相传的Java黄埔军校

    Treeview在winform中的运用(从数据库动态添加节点,增加节点、删除节点、复制节点)

    使用TreeNode的`Clone()`方法可以创建一个与原始节点完全相同的副本。然后,根据需要选择添加副本的位置,可能是同一层级或者作为其他节点的子节点。同时,如果需要保存复制节点的数据,需在数据库中进行相应的复制...

    jquery的clone方法应用于textarea和select的bug修复

    测试发现,textarea和select的jquery的clone方法有问题,textarea和select的值clone的时候会丢掉,发现这个是jquery的一个bug,上不了的可以看下代码,比较简单。就是在clone的时候将val再重新赋值一下,如果知道这个...

    java Clone

    Java中的`clone`方法是Java语言提供的一种复制对象的方式,它允许创建一个对象的副本,这个副本与原对象具有相同的属性值,但它们是两个独立的对象,修改副本不会影响原对象。`clone`方法存在于Java的`java.lang....

    clone()示例源码

    在Java编程语言中,`clone()`方法是一个非常重要的概念,特别是在处理对象复制和克隆时。这个方法源自`Object`类,是所有Java类的基类。`clone()`的使用通常涉及到深度复制和浅复制的概念,这两者在数据结构和内存...

    java clone

    在Java编程语言中,`clone`是一个非常重要的概念,它涉及到对象复制和对象克隆。本文将深入探讨Java中的`clone`方法,包括其工作原理、使用场景、注意事项以及一些个人实践心得。 首先,让我们理解什么是`clone`。...

    jlink v9 warning clone解决

    `jlink v9 warning clone`问题通常涉及到JLink版本9在与MDK配合使用时遇到的警告,提示可能与克隆设备或非法设备相关。 标题中的"jlink v9 warning clone解决"意味着开发者正在尝试解决关于JLink v9版本出现的克隆...

    java object 之clone方法全面解析

    Java中的`clone()`方法是Object类的一个成员方法,它提供了创建一个对象副本的功能。这篇文章将深入探讨`clone()`方法的工作原理、使用场景以及浅拷贝(shallow clone)与深拷贝(deep clone)的区别。 首先,让...

    Java中的clone方法详解_动力节点Java学院整理

    Java中的clone方法详解 在Java语言中,clone方法是一个非常重要的概念,它允许对象被复制,从而创造出一个新的对象。下面我们将详细介绍Java中的clone方法,并讨论它的实现机制和应用场景。 什么是clone方法 ...

    Jlink-clone解决办法,替换文件.rar

    当遇到"Jlink-clone"问题时,这通常指的是遇到了非原厂生产的、可能功能受限或者不稳定版本的J-Link设备。这类克隆设备可能会有兼容性问题、性能下降或不支持某些高级功能。本文将深入探讨如何解决Jlink-clone带来的...

    MinesweeperClone汉化版

    Minesweeper CLone 0.97 Saolei.net扫雷网,小门汉化 Men Shiyun Mine.exe 请自行下载MinesweeperClone_0.97.exe安装后使用

    JQ 创建节点

    本篇文章将深入探讨“JQ创建节点”的知识点,这在构建动态网页时非常关键。 首先,理解DOM(Document Object Model)是至关重要的。DOM是HTML或XML文档的结构化表示,允许程序和脚本动态更新、添加或删除页面元素。...

    JQuery中clone方法复制节点

    JQuery库中的clone方法是其强大的功能之一,它允许开发者复制文档中的元素节点,进而可以将这些副本插入到DOM的其他位置或进行其他操作。在本知识点中,我们将详细介绍JQuery中clone方法复制节点的使用方法,重点...

    Jlink V8固件升级提示Clone的解决方法!

    在使用高版本版KEIL时,提示要升级固件,升级后就出现JLINK is Clone的提示!“the emulator is JLink-Clone, the segger software only support orginal segger device” 然后闪退,IDE崩溃关闭! 解决方案: 1....

    jquery.clone.js

    jquery.clone

    Java clone方法使用

    详细的描述了Java中 clone方法使用

    C#TreeView右键菜单操作在编辑树节点

    TreeNode newNode = copiedNode.Clone() as TreeNode; // 克隆节点 newNode.Text = "粘贴的节点"; insertParent.Nodes.Add(newNode); treeView1.ExpandAll(); } } ``` 在上述代码中,我们只涉及了基本的逻辑。...

    jquery实现 两个select之间option的转移操作

    这里,`find('option')`找到`select1`下的所有`<option>`,然后`each()`遍历每个选项,`clone()`复制选项,最后`append()`将复制的选项添加到`select2`。 对于单选操作,我们可以监听`change`事件,当用户更改选项...

    MySQL Clone Plugin备份同步原理与实践.pptx

    - **并行操作限制**:不允许并行的Clone操作,同一节点不能同时向多个节点发起克隆,多个节点也不能同时向一个节点克隆,以防冲突。 总的来说,MySQL Clone Plugin是MySQL环境中实现快速备份和数据同步的理想选择...

Global site tag (gtag.js) - Google Analytics