如何复制一个元素的所有属性并将它们应用到另一个元素?

IT技术 javascript jquery
2021-02-15 13:18:00

如何将一个元素的属性复制到另一个元素?

HTML

<select id="foo" class="bar baz" style="display:block" width="100" data-foo="bar">...</select>

<div>No attributes yet</div>

JavaScript

var $div = $('div');
var $select = $('select');

//now copy the attributes from $select to $div
6个回答

您可以使用本机Node#attributes属性:http : //jsfiddle.net/SDWHN/16/

var $select = $("select");
var $div = $("div");

var attributes = $select.prop("attributes");

// loop through <select> attributes and apply them on <div>
$.each(attributes, function() {
    $div.attr(this.name, this.value);
});

alert($div.data("foo"));
当您的变量包含对 jQuery 对象的引用时,感谢您在变量前加上 '$'。我在我现在的公司开始了这种趋势......它使快速阅读代码变得更加容易!
2021-04-26 13:18:00
想问一个与此相关的附带问题。我试过了$something.prop('attributes'),它给出了一个带有属性的数组。其中之一是crossorigin用于图像。我试过$item.prop('crossorigin')哪个是未定义的,但如果我尝试$item.prop('src'),它会给出结果。然后我尝试了$item.attr('crossorigin')哪个给出了value。.attr()的区别是.prop()什么?为什么上述情况有些不同?提前致谢。
2021-04-27 13:18:00
请注意:属性数组远不兼容。是的,它是核心,但早期版本的 IE 会随心所欲地对待“核心”属性。我使用“hackish”,但作为从forum.jquery.com/topic /...采取的悖论更合规的方式- 使节点成为字符串表示,用正则表达式更改它的标签并转换回节点。然后我可以重新附加数据和事件。IE 版本在复制某些属性时出错(例如“实现”属性 - 您知道它附加到所有标签吗?)
2021-05-04 13:18:00
@simongcc.propNode代表元素的 DOM的底层本机对象获取一个属性.attr获取以编程方式或通过标记定义的 HTML 属性的值。
2021-05-05 13:18:00

ES6 语法一行:

function cloneAttributes(target, source) {
  [...source.attributes].forEach( attr => { target.setAttribute(attr.nodeName ,attr.nodeValue) })
}

正如第一条评论中所指出的-您可能不想复制源 id 属性……因此,如果您需要参考,此属性会将其保存为“data-id”属性。

function cloneAttributes(target, source) {
  [...source.attributes].forEach( attr => { target.setAttribute(attr.nodeName === "id" ? 'data-id' : attr.nodeName ,attr.nodeValue) })
}
到目前为止最好的答案。现在是 2020 年。
2021-04-17 13:18:00

很简单

function cloneAttributes(element, sourceNode) {
  let attr;
  let attributes = Array.prototype.slice.call(sourceNode.attributes);
  while(attr = attributes.pop()) {
    element.setAttribute(attr.nodeName, attr.nodeValue);
  }
}
另请注意,此方法不会复制任何不必要的原始类型。它只克隆每个属性。
2021-05-06 13:18:00
你有什么理由使用Array#sliceandwhile而不是 justArray#forEach吗?
2021-05-06 13:18:00
可能是为了兼容死浏览器。
2021-05-06 13:18:00

关于 jsfiddle 的工作解决方案

编辑

更新了 jsfiddler

Javascript

$(function(){
    var destination = $('#adiv').eq(0);
    var source = $('#bdiv')[0];

    for (i = 0; i < source.attributes.length; i++)
    {
        var a = source.attributes[i];
        destination.attr(a.name, a.value);
    }
});

HTML

<div id="adiv" class="aclass">A class</div>
<div id="bdiv" class="bclass">B class</div>

这就是将#bdiv属性复制#adiv.

这似乎在 IE (8) 中存在问题,它发现太多属性 (100+) 并且 jQuery 在尝试设置属性时抛出一个成员未找到异常。
2021-04-19 13:18:00
@kingjiv,感谢您的建议。
2021-04-24 13:18:00
您应该至少在此处发布代码的重要部分,如果除了 jsfiddle 消失之外没有其他原因,您的答案仍然存在。
2021-04-25 13:18:00

我们还可以尝试扩展 jQuery 原型 ( $.fn) 对象,以提供可以链接到 jQuery() 函数的新方法。

这是@pimvdb 解决方案的扩展,提供了一个复制所有属性的函数

用法如下:

 $(destinationElement).copyAllAttributes(sourceElement);

扩展函数可以这样定义:

(function ($) {

    // Define the function here
    $.fn.copyAllAttributes = function(sourceElement) {

        // 'that' contains a pointer to the destination element
        var that = this;

        // Place holder for all attributes
        var allAttributes = ($(sourceElement) && $(sourceElement).length > 0) ?
            $(sourceElement).prop("attributes") : null;

        // Iterate through attributes and add    
        if (allAttributes && $(that) && $(that).length == 1) {
            $.each(allAttributes, function() {
                // Ensure that class names are not copied but rather added
                if (this.name == "class") {
                    $(that).addClass(this.value);
                } else {
                    that.attr(this.name, this.value);
                }

            });
        }

        return that;
    }; 

})(jQuery);

http://jsfiddle.net/roeburg/Z8x8x/提供了一个示例

希望这可以帮助。

您的代码具有不必要的重复 jQuery 包装器/初始化。查看我的更改:jsfiddle.net/5eLdcya6
2021-05-14 13:18:00