select节点clone全解析

2009-12-18

在开发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

select节点clone全解析的更多相关文章

  1. 【凯子哥带你学Framework】Activity界面显示全解析

    前几天凯子哥写的Framework层的解析文章<Activity启动过程全解析>,反响还不错,这说明“写让大家都能看懂的Framework解析文章”的思想是基本正确的. 我个人觉得,深入分 ...

  2. (转)ASP.NET缓存全解析6:数据库缓存依赖

    ASP.NET缓存全解析文章索引 ASP.NET缓存全解析1:缓存的概述 ASP.NET缓存全解析2:页面输出缓存 ASP.NET缓存全解析3:页面局部缓存 ASP.NET缓存全解析4:应用程序数据缓 ...

  3. jQuery&nbsp;Ajax&nbsp;实例&nbsp;全解析

    jQuery Ajax 实例 全解析 jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 废话少说,直接进入正题,我 ...

  4. jQuery Ajax 全解析

    转自:http://www.cnblogs.com/qleelulu/archive/2008/04/21/1163021.html 本文地址: jQuery Ajax 全解析 本文作者:QLeelu ...

  5. Oracle AWR报告指标全解析-11011552

    1-5 Top 5 Timed EventsWaits : 该等待事件发生的次数, 对于DB CPU此项不可用Times : 该等待事件消耗的总计时间,单位为秒, 对于DB CPU 而言是前台进程所消 ...

  6. Git全解析之用起来先

    文章目录 1. Git全解析之用起来先 1.1. 先安装Git环境 1.2. 配置 1.3. 简单了解Git 1.3.1. Git对象模型 SHA 1.3.2. Git目录与工作目录 1.4. 可以开 ...

  7. Git全解析之远程仓库交互

    文章目录 1. Git全解析之远程仓库交互 1.1. 中央仓库的概念 1.2. 本地分支与远程分支 1.3. pull与fetch 1.4. 关于捐赠 Git全解析之远程仓库交互 中央仓库的概念 虽然 ...

  8. 【公众号系列】超详细SAP HANA JOB全解析

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[公众号系列]超详细SAP HANA JOB全解 ...

  9. Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析

    Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析 今天发一篇”水文”,可能很多读者都会表示不理解,不过我想把它作为并发序列文章中不可缺少的一块来介绍.本来以为花不了 ...

随机推荐

  1. SQL 设置登录名和密码

    1.打开SQL Server Manager管理器,在左面找到 ‘安全性’ 单击右键 选择‘新建”->“登录”, 如下图 2.弹出对话框,在登录名中输入你的登录号,选择'SQLSERVER身份验 ...

  2. git merge合并时遇上refusing to merge unrelated histories的解决方案

    如果git merge合并的时候出现refusing to merge unrelated histories的错误,原因是两个仓库不同而导致的,需要在后面加上--allow-unrelated-hi ...

  3. [C++ STL] set使用详解

    一.set介绍: set容器内的元素会被自动排序,set与map不同,set中的元素即是键值又是实值,set不允许两个元素有相同的键值.不能通过set的迭代器去修改set元素,原因是修改元素会破坏se ...

  4. {Python}安装第三方包(setup.py)

    在github上下载了records文件到本地. 解压文件 cmd切换到文件setup.py的目录下 先执行 python setup.py build 再执行python setup.py inst ...

  5. LN : leetcode 406 Queue Reconstruction by Height

    lc 406 Queue Reconstruction by Height 406 Queue Reconstruction by Height Suppose you have a random l ...

  6. LN : leetcode 513 Find Bottom Left Tree Value

    lc 513 Find Bottom Left Tree Value 513 Find Bottom Left Tree Value Given a binary tree, find the lef ...

  7. Errors reported here must be corrected before the service can be started

    场景: 安装.配置Apache24时候,最后会给出提示,如图:Errors reported here must be corrected before the service can be star ...

  8. TCP/IP和UDP的比较

    TCP.UDP详解 1.传输层存在的必要性 由于网络层的分组传输是不可靠的,无法了解数据到达终点的时间,无法了解数据未达终点的状态.因此有必要增强网络层提供服务的服务质量. 2.引入传输层的原因 面向 ...

  9. UVM基础之---------uvm factory机制register

    factory机制的一大特点就是根据类的名字来创建类的实例. factory 机制中根据类名来创建类的实例所用到的技术:一是参数化的类,二是静态变量和静态函数.这两者是factory机制实现的根本所在 ...

  10. react Native环境 搭建

    react Native的优点:跨平台 低投入高回报 性能高 支持动态更新.一才两用(ios和Android) 开发成本第 代码复用率高.windows环境搭建react Native开发环境1.安装 ...