用JavaScript复制一个元素(和它的样式) [英] Duplicating an element (and its style) with JavaScript

查看:2236
本文介绍了用JavaScript复制一个元素(和它的样式)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我正在实现的JavaScript库,我需要克隆与原始完全相同的应用样式的元素。虽然我已经获得了一个相当体面的JavaScript知识,作为一种编程语言,在开发它的时候,我仍然是一个DOM脚本新手,所以关于如何实现这一点的任何建议将是非常有用的(并且必须完成



非常感谢您提前。



编辑: cloneNode(true)不会克隆元素的计算样式。假设您有以下HTML:

 < body> 
< p id =origin>这是第一段。< / p>
< div id =destination>
< p>克隆的段落如下:< / p>
< / div>
< / body>

有些样式如:

  body> p {
font-size:1.4em;
font-family:格鲁吉亚;
padding:2em;
background:rgb(165,177,33);
color:rgb(66,52,49);
}

如果您只是克隆元素,请使用以下内容:

  var element = document.getElementById('origin'); 
var copy = element.cloneNode(true);
var destination = document.getElementById('destination');
destination.appendChild(copy);

样式不被克隆。

解决方案

不仅需要克隆,而且您可能想要深入克隆

  node.cloneNode(true); 

文档是这里


如果设置为假,没有
子节点被克隆。节点包含
的任何文本都不会克隆
,因为它包含在一个或
以上的子文本节点中。



如果评估为true,那么整个
子树(包括可能在
子文本节点中的文本)也被复制。对于
空节点(例如IMG和INPUT
元素),
深是否设置为true或false,但
仍然必须提供一个值,这并不重要。 p>

编辑:OP表示 node.cloneNode(true)不复制样式。这是一个简单的测试,显示了使用jQuery和标准DOM API的相反(和期望的效果):

  var node = $(#d1); 

//添加一些任意样式
node.css(height,100px);
node.css(border,1px solid red);

// jQuery clone
$(body)。append(node.clone(true));

//标准DOM克隆(使用节点[0]获取实际的DOM节点)
$(body)。append(node [0] .cloneNode(true));

结果可见: http://jsbin.com/egice3/



编辑2



<希望你以前会提到过;)计算风格完全不同于。更改您的CSS选择器或应用该样式作为一个类,您将有一个解决方案。



编辑3



因为这个问题是一个合法的问题,我没有找到任何好的解决方案,所以很麻烦我想出了以下几点。这不是特别优美的,但是它完成了工作(仅在FF 3.5中测试)。

  var realStyle = function(_elem, _style){
var computedStyle;
if(typeof _elem.currentStyle!='undefined'){
computedStyle = _elem.currentStyle;
} else {
computedStyle = document.defaultView.getComputedStyle(_elem,null);
}

return _style? computedStyle [_style]:computedStyle;
};

var copyComputedStyle = function(src,dest){
var s = realStyle(src);
(var i in s){
//不要使用`hasOwnProperty`,没有什么会被复制
if(typeof i ==string&& i!= cssText&/\d/.test(i)){
//该尝试仅适用于setter属性
try {
dest.style [i] = s [一世];
//`fontSize`在`font`之前,如果`font`为空,`fontSize`将
//覆盖。所以请确保重置此属性。 (hackyhackhack)
//其他属性可能需要类似的处理
if(i ==font){
dest.style.fontSize = s.fontSize;
}
} catch(e){}
}
}
};

var element = document.getElementById('origin');
var copy = element.cloneNode(true);
var destination = document.getElementById('destination');
destination.appendChild(copy);
copyComputedStyle(element,copy);

请参阅PPK的文章标题为获取样式了解更多信息和一些注意事项。


For a JavaScript library I'm implementing, I need to clone an element which has exactly the same applied style than the original one. Although I've gained a rather decent knowledge of JavaScript, as a programming language, while developing it, I'm still a DOM scripting newbie, so any advice about how this can be achieved would be extremely helpful (and it has to be done without using any other JavaScript library).

Thank you very much in advance.

Edit: cloneNode(true) does not clone the computed style of the element. Let's say you have the following HTML:

<body>
  <p id="origin">This is the first paragraph.</p>
  <div id="destination">
    <p>The cloned paragraph is below:</p>
  </div>
</body>

And some style like:

body > p {
  font-size: 1.4em;
  font-family: Georgia;
  padding: 2em;
  background: rgb(165, 177, 33);
  color: rgb(66, 52, 49);
}

If you just clone the element, using something like:

var element = document.getElementById('origin');
var copy = element.cloneNode(true);
var destination = document.getElementById('destination');
destination.appendChild(copy);

Styles are not cloned.

解决方案

Not only will you need to clone, but you'll probably want to do deep cloning as well.

node.cloneNode(true);

Documentation is here.

If deep is set to false, none of the child nodes are cloned. Any text that the node contains is not cloned either, as it is contained in one or more child Text nodes.

If deep evaluates to true, the whole subtree (including text that may be in child Text nodes) is copied too. For empty nodes (e.g. IMG and INPUT elements) it doesn't matter whether deep is set to true or false but you still have to provide a value.

Edit: OP states that node.cloneNode(true) wasn't copying styles. Here is a simple test that shows the contrary (and the desired effect) using both jQuery and the standard DOM API:

var node = $("#d1");

// Add some arbitrary styles
node.css("height", "100px"); 
node.css("border", "1px solid red");

// jQuery clone
$("body").append(node.clone(true));

// Standard DOM clone (use node[0] to get to actual DOM node)
$("body").append(node[0].cloneNode(true)); 

Results are visible here: http://jsbin.com/egice3/

Edit 2

Wish you would have mentioned that before ;) Computed style is completely different. Change your CSS selector or apply that style as a class and you'll have a solution.

Edit 3

Because this problem is a legitimate one that I didn't find any good solutions for, it bothered me enough to come up with the following. It's not particularily graceful, but it gets the job done (tested in FF 3.5 only).

var realStyle = function(_elem, _style) {
    var computedStyle;
    if ( typeof _elem.currentStyle != 'undefined' ) {
        computedStyle = _elem.currentStyle;
    } else {
        computedStyle = document.defaultView.getComputedStyle(_elem, null);
    }

    return _style ? computedStyle[_style] : computedStyle;
};

var copyComputedStyle = function(src, dest) {
    var s = realStyle(src);
    for ( var i in s ) {
        // Do not use `hasOwnProperty`, nothing will get copied
        if ( typeof i == "string" && i != "cssText" && !/\d/.test(i) ) {
            // The try is for setter only properties
            try {
                dest.style[i] = s[i];
                // `fontSize` comes before `font` If `font` is empty, `fontSize` gets
                // overwritten.  So make sure to reset this property. (hackyhackhack)
                // Other properties may need similar treatment
                if ( i == "font" ) {
                    dest.style.fontSize = s.fontSize;
                }
            } catch (e) {}
        }
    }
};

var element = document.getElementById('origin');
var copy = element.cloneNode(true);
var destination = document.getElementById('destination');
destination.appendChild(copy);
copyComputedStyle(element, copy);

See PPK's article entitled Get Styles for more information and some caveats.

这篇关于用JavaScript复制一个元素(和它的样式)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆