对于我正在实现的JavaScript库,我需要来克隆一个与原始完全相同的应用样式的元素。虽然我已经获得了相当不错的JavaScript知识,作为一种编程语言,在开发它时,我仍然是一个DOM脚本新手,所以任何有关如何实现这一点的建议都会非常有用(并且必须要做到这一点)不使用任何其他JavaScript库。)
非常感谢你。
编辑:cloneNode(true)
不克隆元素的计算样式。假设您有以下HTML:
<body>
<p id="origin">This is the first paragraph.</p>
<div id="destination">
<p>The cloned paragraph is below:</p>
</div>
</body>
还有一些风格:
body > p {
font-size: 1.4em;
font-family: Georgia;
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);
未克隆样式。
答案 0 :(得分:28)
您不仅需要克隆,而且您可能还想进行深度克隆。
node.cloneNode(true);
文档为here。
如果深设置为false,则不是 子节点被克隆。任何文字 节点包含未克隆 或者,因为它包含在一个或 更多子文本节点。
如果深评估为真,那么整个 子树(包括可能在的子句) 子文本节点)也被复制。对于 空节点(例如IMG和INPUT 元素)无论是否 深度设置为真或假,但你 还是要提供一个价值。
编辑:OP声明node.cloneNode(true)
不是复制样式。这是一个简单的测试,它使用jQuery和标准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));
结果显示在此处:http://jsbin.com/egice3/
希望你之前提到过;)计算风格完全不同。更改CSS选择器或将该样式应用为类,您将获得解决方案。
因为这个问题是合法的,我没有找到任何好的解决方案,所以我很费力地想出以下内容。它不是特别优雅,但它完成了工作(仅在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);
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);
有关更多信息和一些警告,请参阅PPK的文章Get Styles。
答案 1 :(得分:6)
在通过WEB查看几个好的解决方案后,我决定将每个方面的所有最佳方面结合起来并提出这个问题。
我用简单的超快速Javascript离开了我的解决方案,这样每个人都可以翻译成他们最新的和本月最好的JS风格。
代表马尼拉的香草.....
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="vertical"
android:background="@drawable/background_light_grey"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:padding="5dp"
tools:context="**********">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:scrollbars="vertical"
>
<!-- lot of views, i cut them couse it was something near to 200 rows -->
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
答案 2 :(得分:0)
这些都没有为我工作,但我是根据路易吉的回答提出的。
copyStyles(source: HTMLElement, destination: HTMLElement) {
// Get a list of all the source and destination elements
const srcElements = <HTMLCollectionOf<HTMLElement>>source.getElementsByTagName('*');
const dstElements = <HTMLCollectionOf<HTMLElement>>destination.getElementsByTagName('*');
// For each element
for (let i = srcElements.length; i--;) {
const srcElement = srcElements[i];
const dstElement = dstElements[i];
const sourceElementStyles = document.defaultView.getComputedStyle(srcElement, '');
const styleAttributeKeyNumbers = Object.keys(sourceElementStyles);
// Copy the attribute
for (let j = 0; j < styleAttributeKeyNumbers.length; j++) {
const attributeKeyNumber = styleAttributeKeyNumbers[j];
const attributeKey: string = sourceElementStyles[attributeKeyNumber];
dstElement.style[attributeKey] = sourceElementStyles[attributeKey];
}
}
}