Tem uma prática recomendada em usar setAttribute
lugar do ponto (.
notação de atributo )?
Por exemplo:
myObj.setAttribute("className", "nameOfClass");
myObj.setAttribute("id", "someID");
ou
myObj.className = "nameOfClass";
myObj.id = "someID";
javascript
attributes
setattribute
Francisc
fonte
fonte
.setAttribute()
para[key] = value
, tudo começou a funcionar magicamente.Respostas:
Você deve sempre usar o direto
.attribute
formulário (mas consulte o link quirksmode abaixo) se desejar acesso programático em JavaScript. Ele deve lidar com os diferentes tipos de atributos (pense em "onload") corretamente.Use
getAttribute
/setAttribute
quando desejar lidar com o DOM como ele é (por exemplo, apenas texto literal). Navegadores diferentes confundem os dois. Consulte Modos Quirks: compatibilidade de atributos (in) .fonte
Do Javascript: O Guia Definitivo , esclarece as coisas. Ele observa que HTMLElement objetos de um documento HTML definem propriedades JS que correspondem a todos os atributos HTML padrão.
Portanto, você só precisa usar
setAttribute
atributos não padrão.Exemplo:
fonte
node.frameborder
NÃO está definido, portanto você deve getAttribute para recuperar o valor.frameBorder
diretamente, mas observe a capitalização. Alguém pensou que era uma boa idéia camelCase os equivalentes JavaScript dos atributos HTML. Não consegui encontrar nenhuma especificação para isso, mas a rede parece concordar que se trata de 12 casos específicos (pelo menos para o HTML 4). Veja, por exemplo, o seguinte post: drupal.org/node/1420706#comment-6423420usemap
atributo não pode ser definido usando a notação de ponto ao criar o mapa dinamicamente para uma imagem. Requerimg.setAttribute('usemap', "#MapName");
Sua resposta implica queusemap
é, portanto, "fora do padrão"?Nenhuma das respostas anteriores está completa e a maioria contém informações erradas.
Existem três maneiras de acessar os atributos de um DOM elemento em JavaScript. Todos os três funcionam de maneira confiável nos navegadores modernos, desde que você saiba como utilizá-los.
1
element.attributes
Os elementos têm atributos de propriedade que retornam um NamedNodeMap de objetos Attr ativos . Os índices desta coleção podem ser diferentes entre os navegadores. Portanto, o pedido não é garantido.
NamedNodeMap
possui métodos para adicionar e remover atributos (getNamedItem
esetNamedItem
, respectivamente).Observe que, embora o XML seja explicitamente sensível a maiúsculas e minúsculas, a especificação do DOM solicita que os nomes de cadeias sejam normalizados ; portanto, os nomes passados
getNamedItem
são efetivamente sem distinção entre maiúsculas e minúsculas.Exemplo de uso:
2.
element.getAttribute
&element.setAttribute
Esses métodos existem diretamente no
Element
sem a necessidade de acessarattributes
e seus métodos, mas executam as mesmas funções.Novamente, observe que o nome da string não diferencia maiúsculas de minúsculas.
Exemplo de uso:
3. Propriedades no objeto DOM, como
element.id
Muitos atributos podem ser acessados usando propriedades convenientes no objeto DOM. Quais atributos existem dependem do tipo do nó DOM, não quais atributos são definidos no HTML. As propriedades são definidas em algum lugar da cadeia de protótipos do objeto DOM em questão. As propriedades específicas definidas dependerão do tipo de elemento que você está acessando. Por exemplo,
className
eid
são definidosElement
e existem em todos os nós do DOM que são elementos ( por exemplo, não nós de texto ou comentário). Masvalue
é mais estreito. Está definidoHTMLInputElement
e pode não existir em outros elementos.Observe que as propriedades do JavaScript diferenciam maiúsculas de minúsculas. Embora a maioria das propriedades use letras minúsculas, algumas são camelCase. Portanto, sempre verifique as especificações para ter certeza.
Este "gráfico" captura uma parte da cadeia de protótipos para esses objetos DOM. Não está nem perto de terminar, mas captura a estrutura geral.
Exemplo de uso:
Advertência: Esta é uma explicação de como a especificação HTML define e os navegadores modernos lidam com atributos. Não tentei lidar com as limitações de navegadores antigos e quebrados. Se você precisar oferecer suporte a navegadores antigos, além dessas informações, precisará saber o que está quebrado nesses navegadores.
fonte
Um caso que descobri onde
setAttribute
é necessário é ao alterar os atributos do ARIA, pois não há propriedades correspondentes. Por exemploNão há
x.arialabel
nada disso, então você precisa usar o setAttribute.Edit: x ["aria-label"] não funciona . Você realmente precisa de setAttribute.
fonte
Essas respostas não estão realmente abordando a grande confusão entre propriedades e atributos . Além disso, dependendo do protótipo Javascript, às vezes você pode usar a propriedade de um elemento para acessar um atributo e às vezes não.
Primeiro, você deve se lembrar que an
HTMLElement
é um objeto Javascript. Como todos os objetos, eles têm propriedades. Claro, você pode criar uma propriedade chamada quase tudo o que deseja dentroHTMLElement
, mas não precisa fazer nada com o DOM (o que está na página). A notação de ponto (.
) é para propriedades . Agora, existem algumas propriedades especiais que são mapeadas para atributos e, no momento ou por escrito, existem apenas 4 garantidas (mais sobre isso posteriormente).Todos os
HTMLElement
s incluem uma propriedade chamadaattributes
.HTMLElement.attributes
é uma vivoNamedNodeMap
objecto que se relaciona com os elementos no DOM. "Ao vivo" significa que quando o nó muda no DOM, eles mudam no lado do JavaScript e vice-versa. Os atributos DOM, nesse caso, são os nós em questão. ANode
possui uma.nodeValue
propriedade que você pode alterar.NamedNodeMap
objetos têm uma função chamadasetNamedItem
onde você pode alterar o nó inteiro. Você também pode acessar diretamente o nó pela chave. Por exemplo, você pode dizer.attributes["dir"]
qual é o mesmo que.attributes.getNamedItem('dir');
(Nota lateral, nãoNamedNodeMap
diferencia maiúsculas de minúsculas, para que você também possa passar'DIR'
);Existe uma função semelhante diretamente na
HTMLElement
qual você pode simplesmente chamar,setAttribute
que criará automaticamente um nó se ele não existir e definirá onodeValue
. Também existem alguns atributos aos quais você pode acessar diretamente como propriedades porHTMLElement
meio de propriedades especiais , comodir
. Aqui está um mapeamento aproximado da aparência:Então você pode alterar os
dir
atributos de 6 maneiras:Você pode atualizar todas as propriedades com métodos # 1-5, mas apenas
dir
,id
,lang
, eclassName
com o método # 6.Extensões de HTMLElement
HTMLElement
tem essas 4 propriedades especiais. Alguns elementos são classes estendidas deHTMLElement
propriedades ainda mais mapeadas. Por exemplo,HTMLAnchorElement
temHTMLAnchorElement.href
,HTMLAnchorElement.rel
eHTMLAnchorElement.target
. Mas, cuidado , se você definir essas propriedades em elementos que não possuem essas propriedades especiais (como em aHTMLTableElement
), os atributos não serão alterados e serão apenas propriedades personalizadas normais. Para entender melhor, aqui está um exemplo de sua herança:Propriedades personalizadas
Agora, o grande aviso: como todos os objetos Javascript , você pode adicionar propriedades personalizadas. Mas isso não muda nada no DOM. Você pode fazer:
Mas é o mesmo que
Isso significa que a adição de uma propriedade customizada não será vinculada
.attributes[attr].nodeValue
.atuação
Criei um caso de teste jsperf para mostrar a diferença: https://jsperf.com/set-attribute-comparison . Basicamente, em ordem:
dir
,id
,className
).element.attributes.ATTRIBUTENAME.nodeValue =
element.attributes.getNamedItem(ATTRIBUTENAME).nodeValue = newValue
element.attributes.ATTRIBUTENAME = newNode
element.attributes.setNamedItem(ATTRIBUTENAME) = newNode
Conclusão (TL; DR)
Use os mapeamentos de propriedades especiais de
HTMLElement
:element.dir
,element.id
,element.className
, ouelement.lang
.Se você tiver 100% de certeza de que o elemento é estendido
HTMLElement
com uma propriedade especial, use esse mapeamento especial. (Você pode verificar comif (element instanceof HTMLAnchorElement)
).Se você tem 100% de certeza de que o atributo já existe, use
element.attributes.ATTRIBUTENAME.nodeValue = newValue
.Caso contrário, use
setAttribute()
.fonte
classList
é 100% garantido que existe, mas não é uma propriedade de string, é umDOMTokenList
objeto ativo. Definir.className
diretamente é mais rápido do que manipularclassList
, mas você substituirá a coisa toda..value
, altera o valor interno deHTMLInputElement
, que é refletido nos atributos. Eles também não precisam serstring
..valueAsNumber
mudarávalue
internamente e suastring
forma aparecerá novalue
atributo developer.mozilla.org/pt-BR/docs/Web/HTML/Attributes"Quando usar setAttribute vs .attribute = em JavaScript?"
Uma regra geral é usar
.attribute
e verificar se funciona no navegador...Se funcionar no navegador, você está pronto para ir.
..Se não, use em
.setAttribute(attribute, value)
vez de.attribute
para esse atributo.Repita a lavagem para todos os atributos.
Bem, se você é preguiçoso, pode simplesmente usar
.setAttribute
. Isso deve funcionar bem na maioria dos navegadores. (Embora os navegadores compatíveis.attribute
possam otimizá-lo melhor que.setAttribute(attribute, value)
.)fonte
Parece um caso em que é melhor usar setAttribute:
Dev.Opera - JavaScript eficiente
fonte
posElem.style = newStyle
funciona em todos os navegadores (funcionou para mim no Firefox)? É apenas por razões de desempenho quesetAttribute
é preferido, evitando os repain? ÉposElem.style.cssText = newStyle
mais perfomrant entãoposElem.style = newStyle
?métodos para definir atributos (por exemplo, classe) em um elemento: 1. el.className = string 2. el.setAttribute ('class', string) 3. el.attributes.setNamedItem (objeto) 4. el.setAttributeNode (nó)
Fiz um teste simples de benchmark ( aqui )
e parece que setAttributeNode é cerca de três vezes mais rápido que o setAttribute.
portanto, se o desempenho for um problema - use "setAttributeNode"
fonte
Publicação interessante do script da API do Google sobre isso:
Eles fazem assim:
Observe como eles usam
setAttribute
para "src" e "nonce", mas depois.async = ...
para o atributo "async".Não tenho 100% de certeza, mas provavelmente é porque o "assíncrono" é suportado apenas em navegadores que suportam
.attr =
atribuição direta . Portanto, não faz sentido tentar,sestAttribute("async")
porque se o navegador não entender.async=...
- ele não entenderá o atributo "async".Felizmente, esse é um insight útil do meu projeto de pesquisa em andamento "Desminificar GAPI" . Corrija-me se eu estiver errado.
fonte