JavaScript를 사용하여 한 번에 요소의 여러 속성 설정


88

JavaScript로 한 번에 여러 속성을 설정하려면 어떻게해야합니까? 불행히도이 프로젝트에서 jQuery와 같은 프레임 워크를 사용할 수 없습니다. 지금 내가 가진 것은 다음과 같습니다.

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

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

1
@Quantastical using의 답변은 Object.assign()도우미 함수를 만들고 싶지 않은 사람들을 찾아 볼 가치가 있습니다. "모든 열거 가능 하고 고유 한 속성"에 대해 작동합니다 .
benvc

4
나는이 질문이 게시 된 후 7 년 안에 일종의 ES7 업데이트가있을 것으로 기대하면서 모든 답변을 스크롤하여
@Ariel

답변:


119

도우미 기능을 만들 수 있습니다.

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

다음과 같이 호출하십시오.

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

1
글쎄 그것은 또한 한 번에 아니므로 성능에 영향을 미치지 않습니다.
vsync 2014 년

이것은 그가 요청한 것이 아닙니다. 성능을 개선하는 방법을 알아야합니다
jbartolome 2015

19
@jbartolome- "성능"이라는 단어는 질문에서 한 번 언급되지 않았습니다. 나는 당신이 그 개념을 어디서 얻었는지 모르겠습니다. 질문은 수동으로 elem.setAttribute()여러 번 전화 할 필요가없는 방법을 찾고있는 것으로 보입니다 .
jfriend00

질문이 정말로 원하는 것이 무엇인지 잘 모르겠습니다. 바람직한 결과는 attributeChangedCallback을 "한 번만"호출하는 것입니다. 두 개의 속성에 의존하는 함수를 호출해야하는 경우 일반적으로 attributeChangedCallback은 각 속성 변경에 대해 하나씩 두 번 호출됩니다. 두 속성 모두에 대해 this.getAttribute ( 'your-attr')에 액세스하고 둘 중 하나가 여전히 비어있는 경우 종료하는 것이 첫 번째 솔루션이지만 하나의 속성 만 설정되고 다른 하나는 이미 이전 값이있는 경우를 처리하지 않습니다. . 그러나 신은 이것이 실제로 객관적인 질문이 아닙니다. 쉬운 일이 아닙니다!
Vladimir Brasil

21

를 사용 Object.assign(...)하여 생성 된 요소에 속성을 적용 할 수 있습니다 . 자세한 내용은 주석을 참조하십시오.

명심 height하고 width있습니다 속성 픽셀 단위로 정의 하지 퍼센트. 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 }


1
속성, elem.height 등은 읽기 전용이므로 실패합니다. 설명자를 살펴본 결과, getter (정의되지 않은 setter) 만있는 접근 자입니다.
lukeuser

@lukeuser 의견을 보내 주셔서 감사합니다. 해당 속성이 읽기 전용인지 몰랐습니다.
사용자

2
"당신은 그저 ..."에 대한 당신의 질문에, 나는 당신이 실제로 할 수 없을 때 아마도 이것을 물었습니다.
JP Silvashy

2
@JPSilvashy 나는 내 "당신이 단지"를 무시하거나 우월의 표시를 보여줄 의도가 없었습니다. 그랬다면 죄송합니다. 솔직히 저는 JavaScript 닌자가 아니기 때문에 이것이 적절한 대답이 될지 확신하지 못했기 때문에 lukeuser와 같은 다른 사람들이 논리를 확고히하는 데 도움이되기를 바랐습니다.
사용자

13

프레임 워크 -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이벤트가 아닌을 처리 합니다.

선적 서류 비치


기록을 위해 : IE7 ->'Element' is undefined
KooiInc

예, 충분히 공평합니다. IE7과 그 COM 개체를 잊어 버렸습니다. 이를 오버로드 document.createElement하고 document.getElementByIdshim 할 수 있습니다 . 또는 함수에 기능을 래핑 할 수도 있습니다. 편집 대답은 그 노트 포함하는
크리스 베이커

2
보다 단순화 된 재귀 버전 : jsfiddle 에는 IE shim이 포함되어 있습니다.
Keleko 2014-06-30

나는 Keleko 단순화 버전을 정말 좋아합니다! 유일한 것은 귀하의 버전에는 JSFiddle에 innerText가 없다는 것입니다. 나는 else if (at [prop] === html) {this.innerHTML = set [prop]; } 작동하지 않았습니다. 오류가 발생합니다. innerText 설정을 추가하려면 어떻게해야합니까?
제시카

이 답변을 사용하면 요소 속성, CSS 속성 (중첩 된 개체에있을 수 있음) 및 innerHTML을 포함하는 단일 개체를 사용할 수 있습니다. 또한이를 사용하여 요소 프로토 타입 (hmmm)을 수정하거나 일반 함수 (ahhh)로 사용하는 방법을 보여줍니다. 좋은 작업!
Andrew Willems

12

가변 개수의 인수를받는 함수를 만들 수 있습니다.

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/


11

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%' });

5
const setAttributes = (el, attrs) =>
  Object.entries(attrs)
    .forEach(args =>
      el.setAttribute(...args))

4

또는 매개 변수의 속성을 포함하는 요소를 만드는 함수를 만듭니다.

function elemCreate(elType){
  var element = document.createElement(elType);
  if (arguments.length>1){
    var props = [].slice.call(arguments,1), key = props.shift();
    while (key){ 
      element.setAttribute(key,props.shift());
      key = props.shift();
    }
  }
  return element;
}
// usage
var img = elemCreate('img',
            'width','100',
            'height','100',
            'src','http://example.com/something.jpeg');

참고 : height/width='100%'속성을 사용하여 작동하지 않습니다. 높이 / 너비가 100 % 인 경우 요소가 필요합니다.style.height/style.width


@vsync 귀하의 무작위 반대 투표와 모욕에 감사 드리지만 여기에 다른 답변과 근본적인 차이가 거의 없습니다. 진정해.
Chris Baker

@Chris-무작위 예였습니다. 대신이 답변을 홍보하고 싶었 기 때문에 위에있는 답변에 반대 투표를해야했습니다. 예, 1000 개의 항목이 있고 각각에 대해 5 개의 속성을 변경해야하는 경우 DOM에 5000 번 액세스하는 것보다 새 속성으로 항목을 다시 만드는 것이 가장 좋습니다. 동의하지 않습니까?
vsync 2014 년

@vsync 사용 사례에 상속되는 특수 성능을 고려하지 않고 StackOverflow에서 찾은 임의 복사 / 붙여 넣기 기능을 사용하는 경우 더 큰 문제가있을 수 있습니다. 또한 귀하가 반대 투표를 한 답변에서 DOM에 5000 번 액세스하지 않을 것입니다.이 답변보다 많지 않습니다. 두 경우 모두 문제의 요소가 DOM 트리에 삽입되지 않았습니다. 이 대답과 내 대답은 똑같은 일을하며 단순히 속성을 다르게 반복합니다.
Chris Baker

@Chris-이 질문은 저와 관련이 없습니다. 왜 나에 대해 말하고 내가 뭘하는지 말지? 관련이 없습니다. DOM 자체에서 많은 노드의 속성을 변경해야하는 경우 귀하의 대답은 그다지 좋지 않지만,이 대답은 모든 속성으로 노드를 다시 만들고 다시 만드는 좋은 사고 방식을 촉진하기 때문에 약간 더 좋습니다. DOM에 설치하십시오. clone방법을 사용하는 것이 선호 되기 때문에 이것은 또한 이상적이지 않습니다 . 전체 노드를 처음부터 만들 필요가 없습니다. 어쨌든 가장 일반적인 사용 사례 인 DOM에 대한 액세스를 최소화하는 것이 가장 중요합니다.
vsync 2014 년

@vsync "당신"이라는 단어는 추상적 인 의미로 사용됩니다. 이는 당신을 개인 (당신이 vsynch, 알고 있습니다)이라는 의미가 아니라 이러한 답변의 가상 미래 소비자를 의미합니다. 다시 한 번 두 가지 대답은 기능면에서 동일합니다. 추론에 결함이 있어도 원하는 방식으로 투표 할 수 있지만 (벤치 마크를 확인) 자신에게 속삭이는 발언을 유지하십시오.
Chris Baker

3

이 시도

function setAttribs(elm, ob) {
    //var r = [];
    //var i = 0;
    for (var z in ob) {
        if (ob.hasOwnProperty(z)) {
            try {
                elm[z] = ob[z];
            }
            catch (er) {
                elm.setAttribute(z, ob[z]);
            }
        }
    }
    return elm;
}

데모 : 여기


1

이 기능을 사용하여 속성을 동시에 만들고 설정합니다.

function createNode(node, attributes){
    const el = document.createElement(node);
    for(let key in attributes){
        el.setAttribute(key, attributes[key]);
    }
    return el;
}

그렇게 사용

const input = createNode('input', {
    name: 'test',
    type: 'text',
    placeholder: 'Test'
});
document.body.appendChild(input);

1

이 클래스의 모든 요소에 대해 한 번에 속성을 설정하는 가장 좋은 방법이라고 생각합니다.

function SetAtt(elements, attributes) {
    for (var element = 0; element < elements.length; element++) {
        for (var attribute = 0; attribute < attributes.length; attribute += 2) {
            elements[element].setAttribute(attributes[attribute], attributes[attribute + 1]);
        }
    }
}
var Class = document.getElementsByClassName("ClassName"); // class array list
var Data = ['att1', 'val1', 'att2', 'val2', 'att3', 'val3']; //attributes array list
SetAtt(Class, Data);

1

다음과 같이 "Element"프로토 타입에 메소드 (setAttributes, 끝에 "s"포함)를 추가 할 수 있습니다.

Element.prototype.setAttributes = function(obj){
  for(var prop in obj) {
    this.setAttribute(prop, obj[prop])
  }
}

한 줄로 정의 할 수 있습니다.

Element.prototype.setAttributes = function(obj){ for(var prop in obj) this.setAttribute(prop, obj[prop]) }

다른 메서드를 호출 할 때 정상적으로 호출 할 수 있습니다. 속성은 객체로 제공됩니다.

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

주어진 인수가 객체가 아닌 경우 오류를 발생시키는 if 문을 추가 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.