getAttribute () versus propriedades do objeto Element?

92

As expressões gostam Element.getAttribute("id")e Element.idretornam a mesma coisa.

Qual deve ser usado quando precisamos de atributos de um objeto HTMLElement?

Existe algum problema entre navegadores com esses métodos, como getAttribute()e setAttribute()?

Ou qualquer impacto no desempenho entre o acesso direto às propriedades do objeto e o uso desses métodos de atributos?

PK
fonte
1
Pergunta semelhante: Propriedades e atributos em HTML
sleske

Respostas:

126

getAttributerecupera o atributo de um elemento DOM, enquanto el.idrecupera a propriedade deste elemento DOM. Eles não são os mesmos.

Na maioria das vezes, as propriedades DOM são sincronizadas com atributos.

Porém, a sincronização não garante o mesmo valor . Um exemplo clássico é entre el.hrefe el.getAttribute('href')para um elemento âncora.

Por exemplo:

<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

Este comportamento ocorre porque de acordo com o W3C , a propriedade href deve ser um link bem formado. A maioria dos navegadores respeita esse padrão (adivinhe quem não?).

Há um outro caso para o input's checkedpropriedade. A propriedade DOM retorna trueou falseenquanto o atributo retorna a string "checked"ou uma string vazia.

E então, existem algumas propriedades que são sincronizadas unilateralmente apenas . O melhor exemplo é a valuepropriedade de um inputelemento. Alterar seu valor por meio da propriedade DOM não alterará o atributo (editar: verifique o primeiro comentário para obter mais precisão).

Por esses motivos, sugiro que você continue usando as propriedades DOM , e não os atributos, pois seu comportamento difere entre os navegadores.

Na realidade, existem apenas dois casos em que você precisa usar os atributos:

  1. Um atributo HTML personalizado, porque não é sincronizado com uma propriedade DOM.
  2. Para acessar um atributo HTML embutido, que não é sincronizado da propriedade, e você tem certeza de que precisa do atributo (por exemplo, o original valuede um inputelemento).

Se você quiser uma explicação mais detalhada, eu sugiro fortemente que você leia esta página . Demorará apenas alguns minutos, mas ficará encantado com as informações (que resumi aqui).

Florian Margaine
fonte
9
1 para obter bons conselhos em geral. No entanto, a sincronização está um pouco errada: a valuepropriedade de uma entrada obtém seu valor inicial do atributo, mas de outra forma não está ligada a ele. O valueatributo é totalmente sincronizado em vez da defaultValuepropriedade. Da mesma forma checkede defaultChecked. Exceto no antigo IE (<= 7 e modos de compatibilidade posteriores), que quebrou getAttribute()e setAttribute().
Tim Down
Adicionado seu comentário como "explicação adicional" :-)
Florian Margaine
2
Acho que você entendeu o primeiro exemplo errado. a.hrefretorna o URL completo, a.getAttribute("href")retorna o atributo exatamente como defiend na fonte HTML.
Salman A
Se você está tentando descobrir se um valor não é padrão, é melhor usar atributos. Muitos navegadores modernos retornarão um valor padrão (por exemplo input.formAction) ou string vazia (por exemplo a.download), o que torna as coisas ambíguas. A única exceção são os valores que não são sincronizados bidirecionais, como value.
Kevin Li
Se id não for definido no dom, getAttribute retornará nulo e element.id retornará uma string vazia. Isso é um padrão?
Maciej Krawczyk
11

getAttribute('attribute') normalmente retorna o valor do atributo como uma string, exatamente como definido no código-fonte HTML da página.

No entanto, element.attributepode retornar um valor normalizado ou calculado do atributo. Exemplos:

  • <a href="https://stackoverflow.com/foo"></a>
    • a.href conterá o URL completo
  • <input type="checkbox" checked>
    • input.checked será verdadeiro (booleano)
  • <input type="checkbox" checked="bleh">
    • input.checked será verdadeiro (booleano)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width será 0 (número) antes de a imagem ser carregada
    • img.width será 64 (número) quando a imagem (ou os primeiros bytes dela) for carregada
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img.width será o calculado 50%
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img.width será 50 (número)
  • <div style='background: lime;'></div>
    • div.style será um objeto
Salman A
fonte
3

.idsalva a sobrecarga da chamada de função. (que é muito pequeno, mas você perguntou.)

gdoron está apoiando Monica
fonte
Hi gdoron, apenas por uma questão de curiosidade: tentei encontrar uma explicação 'oficial' para isso (além do teste empírico, que é bastante claro;)), mas sem sucesso. Você tem algum link sobre isso?
mamoo
3

De acordo com este teste jsPerf getAttribute é mais lento do que idpropriedade.

PS

Curiosamente, ambas as instruções têm um desempenho muito ruim no IE8 (em comparação com outros navegadores).

mamão
fonte
3

Sempre use as propriedades, a menos que tenha um motivo específico para não fazê-lo.

  • getAttribute()e setAttribute()estão quebrados no IE mais antigo (e modo de compatibilidade nas versões posteriores)
  • propriedades são mais convenientes (em particular, aquelas correspondentes a atributos booleanos)

Existem algumas exceções :

  • acessando atributos de <form>elementos
  • acessar atributos personalizados (embora eu desencoraje o uso de atributos personalizados)

Já escrevi sobre esse assunto algumas vezes no SO:

Tim Down
fonte
Antes do IE 8, propriedades e atributos eram tratados de forma idêntica . Como você mencionou anteriormente, as propriedades são o caminho a percorrer.
@MattMcDonald: Sim, esse é o quebrantamento a que estava aludindo. Não expandi nessa resposta porque senti que já tinha feito o suficiente em outras respostas que vinculei :)
Tim Down
0

Experimente o exemplo abaixo para entender isso completamente. Para o DIV abaixo

<div class="myclass"></div>

O Element.getAttribute('class')retornará, myclassmas você deve usar o Element.classNameque o recupera da propriedade DOM.

Hrushikesh
fonte
0

Uma área em que isso faz uma grande diferença é no estilo de CSS com base em atributos.

Considere o seguinte:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>

O div com a propriedade personalizada definida diretamente não reflete o valor do atributo e não é selecionado pelo nosso seletor de atributos (div[custom] ) no css.

O div com o atributo personalizado definido usando setAttribute, no entanto, pode ser selecionado usando um seletor de atributo css e estilizado de acordo.

Jsilvermist
fonte