我一直致力于一个小型项目,我正在使用jQuery .clone()
方法。
与此相关的陷阱是在具有唯一标识符的HTML上使用它。
所以我继续实现getComputedStyle
来查找原始唯一元素的样式属性,以便将其复制到克隆并在之后给出一个新的id(是的,它可以提供性能问题,但它是's}实验性的)。
根据jQuery规范,在克隆之后但在追加之前执行此操作将使操作发生在DOM之外(因此不会发生id'违规'将会发生)。但是当我在克隆对象后尝试查找元素的样式属性时,我注意到浏览器有一些奇怪的行为。在此之前,所有浏览器都会返回相同的值,但在克隆之后:
Firefox - 无忧无虑,有趣的是克隆的计算样式是实际的CSS值而不是计算数据(以像素为单位)。
IE - 似乎有效,但价值不一定正确。
Chrome - 无法计算。这是一个例子:
http://codepen.io/anon/pen/zxqmNK?editors=011
var elements = [];
var objects = [];
$('body').find('[id]').each(function() {
elements.push(this);
});
$('body').clone().find('[id]').each(function() {
objects.push(this);
});
$.each(elements, function(key, element) {
var current = window.getComputedStyle(element, null).getPropertyValue('width');
$('#log').append('<p>' + element.id + ': ' + current + '</p>');
});
$('#log').append('</br>');
$.each(objects, function(count, object) {
var current = window.getComputedStyle(object, null).getPropertyValue('width');
$('#log').append('<p>' + object.id + ': ' + current + '</p>');
});
有人知道这是一个bug还是之前有类似的行为? 网络方面不是很多(甚至不是Stackoverflow)。 提前感谢任何见解。
编辑 - 进行了一些测试,看起来IE的行为与Chrome相同。
只是没有返回任何内容,所有内容都设置为&#39; auto&#39;。
如果使用.css()
访问克隆对象的样式,则所有值都返回0px
(包括背景等属性)。
似乎只有Mozilla会对克隆的对象进行处理,就好像任何样式都已应用于它一样。
答案 0 :(得分:1)
第一种方法
以下是我最初的解决方法......对Mozilla的处理方式不同很诱人,但这需要浏览器嗅探,以便我们能够解决无法访问克隆的风格。
创建具有唯一标识符的两个对象数组 - 第一个包含要从中复制样式的元素,第二个包含要传输样式的克隆元素:
var individual = [], singular = [];
$('.target').find('[id]').each(function() {
individual.push(this);
})
.end().clone().find('[id]').each(function() {
singular.push(this);
});
现在,属性及其值将从存储在DOM中的对象数组复制到克隆中 - 之后,当前标识符的名称将更改为唯一的名称:
$.each(individual, function(key) {
var tag = this.id,
styles = window.getComputedStyle(this, null),
element = singular[key];
$.each(styles, function() {
var value = styles.getPropertyValue(this);
$(element).css(this, value);
});
$(element).attr('id', tag + '-cloned');
});
在此之后插入克隆的项目,因此不会出现双重标识符。请注意,这可能会产生很多样式属性(例如,Firefox中每个对象大约220个)。
var individual = [], singular = [];
$('.target').find('[id]').each(function() {
individual.push(this);
})
.end().clone().find('[id]').each(function() {
singular.push(this);
})
.end().queue(function() {
transFigure();
$(this).dequeue();
})
.appendTo('body');
function transFigure() {
$.each(individual, function(key) {
var tag = this.id,
styles = window.getComputedStyle(this, null),
element = singular[key];
$.each(styles, function() {
var value = styles.getPropertyValue(this);
$(element).css(this, value);
});
$(element).attr('id', tag + '-cloned');
});
}
+++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++
第二种方法
即使以上工作正常,但效率也不高,页面大小调整值可能会开始不同。所以我在遇到JavaScript之后找到了一个更好的解决方案,然后在JavaScript cssRules
上进行一些挖掘。有了这个,你可以直接访问所有样式表!
下面是一支试图解释该过程的笔,但它归结为匹配(使用.test
)克隆中的唯一标识符与样式表中找到的cssText
。然后更改id
并将其存储在数组中,以便以后插入/添加到样式表本身。
除了更有效的方法(不传输所有默认值)之外,还会为所有浏览器而不是计算值复制实际的CSS。还可以包括img
,p
等衍生产品。它甚至可以复制@rules
并以这种方式保持响应能力。
它的本质:
var singular = [], rules = [];
$('#target').clone().find('[id]').each(function() {
singular.push(this);
});
var sheet = document.styleSheets[0],
styles = sheet.cssRules;
$.each(singular, function() {
var selector = '#' + this.id,
pattern = new RegExp(selector + '(:| |,)');
$.each(styles, function() {
var string = this.cssText;
if (pattern.test(string)) {
var rule = string.replace(selector, selector + '-duplicate');
rules.push(rule);
}
});
});
$.each(rules, function() {
var index = styles.length;
sheet.insertRule(this, index);
});
在此之后,可以将克隆插入到DOM中,并应用所有唯一标识符和完整样式。请注意,在上面的示例中,在使用cssRules
时,实际上还没有使代码尽可能可读。图像已预先放入标记中,使用不同的id
- 一个与复制的样式规则匹配的图像。