使用 JavaScript 一次为一个元素设置多个属性

IT技术 javascript
2021-01-29 17:47:22

如何使用 JavaScript 一次设置多个属性?不幸的是,我无法在这个项目中使用像 jQuery 这样的框架。这是我现在所拥有的:

var elem = document.createElement("img");

elem.setAttribute("src", "http://example.com/something.jpeg");
elem.setAttribute("height", "100%");
elem.setAttribute("width", "100%");
6个回答

你可以做一个辅助功能:

function setAttributes(el, attrs) {
  for(var key in attrs) {
    el.setAttribute(key, attrs[key]);
  }
}

像这样调用它:

setAttributes(elem, {"src": "http://example.com/something.jpeg", "height": "100%", ...});
我不确定这个问题真正想要什么。一个好的可能的期望结果是“只调用一次”attributeChangedCallback。如果我需要调用一个依赖于两个属性的函数,通常 attributeChangedCallback 被调用两次,每次属性更改一次。访问这两个属性的 this.getAttribute('your-attr') 并在其中一个仍然为空时退出是第一个解决方案,但它不处理仅设置一个属性而另一个已经具有先前值的情况. 但天助这其实并不是客观的问题。不容易!
2021-03-16 17:47:22
从 ECMAScript 8 开始,您可以使用Object.entries()which 避免必须在原始对象中查找每个值。这允许将函数编写为:function setAttributes(el, attrs) { Object.entries(attrs).forEach(([key, value]) => el.setAttribute(key, value)); }
2021-03-19 17:47:22
@jbartolome - 问题中一次没有提到“性能”这个词。我不知道你从哪里得到这个概念。这个问题似乎正在寻找一种不必多次手动调用的方法elem.setAttribute()
2021-03-20 17:47:22
这不是他问的。我们需要知道如何提高性能
2021-03-25 17:47:22
好吧,它也不是一次,所以不会影响性能。
2021-04-01 17:47:22

您也许可以使用Object.assign(...)将您的属性应用于创建的元素。尽管一些“属性(elem.height 等)是只读的,即只有一个 getter(未定义的 setter)的访问器”。

请记住,heightwidth属性以像素为单位定义,而不是百分比。您必须使用 CSS 使其流畅。

var elem = document.createElement('img')
Object.assign(elem, {
  className: 'my-image-class',
  src: 'https://dummyimage.com/320x240/ccc/fff.jpg',
  height: 120, // pixels
  width: 160, // pixels
  onclick: function () {
    alert('Clicked!')
  }
})
document.body.appendChild(elem)

// One-liner:
// document.body.appendChild(Object.assign(document.createElement(...), {...}))
.my-image-class {
  height: 100%;
  width: 100%;
  border: solid 5px transparent;
  box-sizing: border-box
}

.my-image-class:hover {
  cursor: pointer;
  border-color: red
}

body { margin:0 }

@lukeuser 感谢您的评论。我不知道这些属性是只读的。
2021-03-13 17:47:22
有关其他详细信息,请参阅评论。评论可以随时删除。任何重要的东西都应该添加到帖子中,而不是从帖子中引用。
2021-03-16 17:47:22
对于你关于“你不能只是......”的问题,我可能在你实际上不能只是问这个问题的时候。
2021-03-18 17:47:22
@JPSilvashy 我不打算让我的“你不能只是”贬低或表现出优越感。对不起,如果有。老实说,我不确定这是否是一个合适的答案,因为我不是 JavaScript 忍者,所以我希望像 lukeuser 这样的其他人可以帮助巩固逻辑。
2021-03-19 17:47:22
elem.height 等属性是只读的,因此失败。我查看了描述符,它们是只有一个 getter(未定义的 setter)的访问器。
2021-04-09 17:47:22

如果您需要 framework-esq 语法(注意:仅支持 IE 8+),您可以扩展Element原型并添加您自己的setAttributes功能:

Element.prototype.setAttributes = function (attrs) {
    for (var idx in attrs) {
        if ((idx === 'styles' || idx === 'style') && typeof attrs[idx] === 'object') {
            for (var prop in attrs[idx]){this.style[prop] = attrs[idx][prop];}
        } else if (idx === 'html') {
            this.innerHTML = attrs[idx];
        } else {
            this.setAttribute(idx, attrs[idx]);
        }
    }
};

这让你可以使用这样的语法:

var d = document.createElement('div');
d.setAttributes({
    'id':'my_div',
    'class':'my_class',
    'styles':{
        'backgroundColor':'blue',
        'color':'red'
    },
    'html':'lol'
});

试试看:http : //jsfiddle.net/ywrXX/1/

如果你不喜欢扩展一个宿主对象(有些人反对)或者需要支持 IE7-,就用它作为一个函数

请注意,setAttribute这不适用于styleIE 或事件处理程序(无论如何你都不应该)。上面的代码处理style,但不处理事件。

文档

我真的很喜欢 Keleko 简化版!唯一的问题是,在您的版本中,您的 JSFiddle 中没有 innerText。我尝试添加 else if (at[prop] === html) { this.innerHTML = set[prop]; 它没有用。我收到一个错误。如何添加innerText设置?
2021-03-19 17:47:22
此答案允许您使用包含元素属性、css 属性(可能在嵌套对象中)和 innerHTML 的单个对象。它还展示了如何使用此修改元素原型 (hmmm) 或将其用作普通函数 (ahhh)。不错的工作!
2021-03-21 17:47:22
是的,够公平。忘记了 IE7 和它们的 COM 对象。您可以重载document.createElementdocument.getElementById填充它....或者只是将功能包装在一个函数中。编辑答案以包含该注释
2021-03-22 17:47:22
更简化的递归版本:jsfiddle包含一个 IE 垫片
2021-04-01 17:47:22
备案:IE7 -> 'Element' is undefined
2021-04-11 17:47:22

你可以编写一个 ES5.1 辅助函数:

function setAttributes(el, attrs) {
    Object.keys(attrs).forEach(key => el.setAttribute(key, attrs[key]));
}

像这样调用它:

setAttributes(elem, { src: 'http://example.com/something.jpeg', height: '100%' });

您可以创建一个带有可变数量参数的函数:

function setAttributes(elem /* attribute, value pairs go here */) {
    for (var i = 1; i < arguments.length; i+=2) {
        elem.setAttribute(arguments[i], arguments[i+1]);
    }
}

setAttributes(elem, 
    "src", "http://example.com/something.jpeg",
    "height", "100%",
    "width", "100%");

或者,您在对象上传递属性/值对:

 function setAttributes(elem, obj) {
     for (var prop in obj) {
         if (obj.hasOwnProperty(prop)) {
             elem[prop] = obj[prop];
         }
     }
 }

setAttributes(elem, {
    src: "http://example.com/something.jpeg",
    height: "100%",
    width: "100%"
});

您还可以制作自己的可链接对象包装器/方法:

function $$(elem) {
    return(new $$.init(elem));
}

$$.init = function(elem) {
    if (typeof elem === "string") {
        elem = document.getElementById(elem);
    }
    this.elem = elem;
}

$$.init.prototype = {
    set: function(prop, value) {
        this.elem[prop] = value;
        return(this);
    }
};

$$(elem).set("src", "http://example.com/something.jpeg").set("height", "100%").set("width", "100%");

工作示例:http : //jsfiddle.net/jfriend00/qncEz/