Portanto, o jQuery 1.6 tem a nova função prop()
.
$(selector).click(function(){
//instead of:
this.getAttribute('style');
//do i use:
$(this).prop('style');
//or:
$(this).attr('style');
})
ou, nesse caso, eles fazem a mesma coisa?
E se eu não tem que passar a usar prop()
, todas as antigas attr()
chamadas vai quebrar se eu mudar para 1.6?
ATUALIZAR
selector = '#id'
$(selector).click(function() {
//instead of:
var getAtt = this.getAttribute('style');
//do i use:
var thisProp = $(this).prop('style');
//or:
var thisAttr = $(this).attr('style');
console.log(getAtt, thisProp, thisAttr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id='id' style="color: red;background: orange;">test</div>
(veja também este violino: http://jsfiddle.net/maniator/JpUF2/ )
O console registra getAttribute
como uma sequência e attr
como uma sequência, mas prop
como como CSSStyleDeclaration
, por quê? E como isso afeta minha codificação no futuro?
Respostas:
Atualização 1 de novembro de 2012
Minha resposta original se aplica especificamente ao jQuery 1.6. Meu conselho permanece o mesmo, mas o jQuery 1.6.1 mudou um pouco as coisas: diante da pilha prevista de sites quebrados, a equipe do jQuery voltou
attr()
a algo próximo (mas não exatamente o mesmo) do antigo comportamento dos atributos booleanos . John Resig também escreveu um blog sobre isso . Eu posso ver a dificuldade em que eles estavam, mas ainda discordo de sua recomendação de preferirattr()
.Resposta original
Se você já usou o jQuery e não o DOM diretamente, isso pode ser uma mudança confusa, embora seja definitivamente uma melhoria conceitual. Não é tão bom para os bazilhões de sites que usam jQuery que serão interrompidos como resultado dessa alteração.
Vou resumir os principais problemas:
prop()
e nãoattr()
.prop()
faz o queattr()
costumava fazer. Substituir as chamadasattr()
porprop()
no seu código geralmente funcionará.checked
propriedade é um booleano, astyle
propriedade é um objeto com propriedades individuais para cada estilo, asize
propriedade é um número.value
echecked
: para esses atributos, a propriedade sempre representa o estado atual enquanto o O atributo (exceto nas versões antigas do IE) corresponde ao valor / verificação padrão da entrada (refletida na propriedadedefaultValue
/defaultChecked
).Se você é um desenvolvedor de jQuery e está confuso com toda essa empresa sobre propriedades e atributos, precisa dar um passo atrás e aprender um pouco sobre isso, pois o jQuery não está mais tentando se proteger dessas coisas. Para a palavra autorizada, mas um pouco seca sobre o assunto, há as especificações: DOM4 , HTML DOM , DOM Nível 2 , DOM Nível 3 . A documentação do DOM do Mozilla é válida para a maioria dos navegadores modernos e é mais fácil de ler do que as especificações, portanto, você pode achar útil a referência do DOM . Há uma seção sobre propriedades do elemento .
Como um exemplo de como as propriedades são mais simples de lidar do que os atributos, considere uma caixa de seleção inicialmente marcada. Aqui estão duas partes possíveis de HTML válido para fazer isso:
Então, como você descobre se a caixa de seleção está marcada com jQuery? Observe o Stack Overflow e, normalmente, você encontrará as seguintes sugestões:
if ( $("#cb").attr("checked") === true ) {...}
if ( $("#cb").attr("checked") == "checked" ) {...}
if ( $("#cb").is(":checked") ) {...}
Essa é realmente a coisa mais simples do mundo a ver com a
checked
propriedade booleana, que existe e funciona perfeitamente em todos os principais navegadores de scripts desde 1995:if (document.getElementById("cb").checked) {...}
A propriedade também torna a seleção ou desmarcação da caixa de seleção trivial:
document.getElementById("cb").checked = false
No jQuery 1.6, isso se torna inequivocamente
$("#cb").prop("checked", false)
A idéia de usar o
checked
atributo para criar scripts para uma caixa de seleção é inútil e desnecessária. A propriedade é o que você precisa.checked
atributofonte
value
exemplo de Tim , por exemplo. Uma função chamadaattr
que recupera a propriedadevalue
em vez do atributo "value" não faz muito sentido (e pode ser diferente). No futuro,attr
fazer atributos eprop
fazer propriedades será mais claro, embora a transição seja dolorosa para alguns. Não leve a mal, não há nada como voltar atrás e ler as especificações para ter uma idéia de quais são as propriedades.value
por exemplo), mas vamos tentar ignorá-lo. 99% do tempo, você deseja trabalhar com adereços. Se você precisar trabalhar com um atributo real, provavelmente saberá disso.value
propriedade de uma entrada não altera seuvalue
atributo nos navegadores modernos" Eu não achei que sim, e foi por isso que comecei a usá-la como exemplo, mas quando comecei a codificar o exemplo, se não foi atualizado no Chrome, Firefox, Opera, IE ... - jsbin.com/ahire4 Acontece que é porque eu estava usando uminput[type="button"]
para o meu experimento. Ele não atualiza o atributo em uminput[type="text"]
- jsbin.com/ahire4/2 Falar sobre complicado !! Não apenas o elemento, mas o tipo dela ...Acho que o Tim falou muito bem , mas vamos voltar atrás:
Um elemento DOM é um objeto, uma coisa na memória. Como a maioria dos objetos no OOP, ele possui propriedades . Além disso, também possui um mapa dos atributos definidos no elemento (geralmente provenientes da marcação que o navegador leu para criar o elemento). Algumas das propriedades do elemento obtêm sua inicial valores de atributos com os mesmos nomes ou nomes semelhantes (
value
obtém seu valor inicial do atributo "value";href
obtém seu valor inicial do atributo "href", mas não é exatamente o mesmo valor;className
do atributo "class"). Outras propriedades obtêm seus valores iniciais de outras maneiras: Por exemplo, aparentNode
propriedade obtém seu valor com base no que é seu elemento pai;style
propriedade, tenha ou não um atributo "estilo".Vamos considerar essa âncora em uma página em
http://example.com/testing.html
:Alguma arte ASCII gratuita (e deixando de fora muitas coisas):
Observe que as propriedades e atributos são distintos.
Agora, embora sejam distintos, porque tudo isso evoluiu ao invés de ser projetado desde o início, várias propriedades retornam ao atributo do qual derivaram se você as definir. Mas nem todos o fazem, e como você pode ver de
href
cima, o mapeamento nem sempre é um "repasse de valor" direto, às vezes há interpretação envolvida.Quando falo sobre propriedades como propriedades de um objeto, não estou falando em abstrato. Aqui está um código não-jQuery:
(Esses valores são como na maioria dos navegadores; há algumas variações.)
O
link
objeto é real e você pode ver que há uma distinção real entre acessar uma propriedade e acessar um atributo .Como Tim disse, na grande maioria das vezes, queremos trabalhar com propriedades. Parcialmente, isso ocorre porque seus valores (até mesmo seus nomes) tendem a ser mais consistentes entre os navegadores. Na maioria das vezes, queremos trabalhar com atributos quando não há propriedade relacionada a ele (atributos personalizados) ou quando sabemos que, para esse atributo específico, o atributo e a propriedade não são 1: 1 (como em
href
e "href" acima) .As propriedades padrão estão dispostas nas várias especificações do DOM:
Essas especificações têm excelentes índices e eu recomendo manter os links à mão; Eu os uso o tempo todo.
Os atributos personalizados incluiriam, por exemplo, quaisquer
data-xyz
atributos que você possa colocar em elementos para fornecer metadados ao seu código (agora que é válido a partir do HTML5, desde que você mantenha odata-
prefixo). (As versões recentes do jQuery dão acesso adata-xyz
elementos por meio dadata
função, mas essa função não é apenas um acessador dedata-xyz
atributos [ele faz mais e menos que isso]; a menos que você realmente precise de seus recursos, eu usaria aattr
função para interagir comdata-xyz
atributo.)A
attr
função costumava ter uma lógica complicada em torno de obter o que eles pensavam que você queria, em vez de literalmente obter o atributo. Confundiu os conceitos. Mover-se paraprop
eattr
pretendia desconstruí-los. Resumidamente em v1.6.0 jQuery foi longe demais a esse respeito, mas a funcionalidade foi rapidamente adicionado de volta paraattr
lidar com as situações comuns onde as pessoas usamattr
quando tecnicamente eles devem usarprop
.fonte
.attr('class', 'bla')
funciona como esperado para mim em 1.7.0 , 1.7.1 e 1.7.2 no Chrome 17, Firefox 11, Opera 11, IE6, IE8, IE9 e Safari 5..data
- lerá o valor padrão do atributo, se presente, mas se você escrever nele, ele mudará uma propriedade oculta do elemento e não atualizará o atributo.Essa mudança foi um longo tempo para o jQuery. Durante anos, eles se contentaram com uma função chamada
attr()
que recuperou principalmente as propriedades do DOM, e não o resultado que você esperaria do nome. A segregaçãoattr()
eprop()
deve ajudar a aliviar parte da confusão entre atributos HTML e propriedades DOM.$.fn.prop()
agarra a propriedade DOM especificada, enquanto$.fn.attr()
agarra o atributo HTML especificado.Para entender completamente como eles funcionam, aqui está uma explicação detalhada sobre a diferença entre atributos HTML e propriedades DOM:
Atributos HTML
Sintaxe:
<body onload="foo()">
Objetivo: Permite que a marcação tenha dados associados a ela para eventos, renderização e outros fins.
Visualização: O atributo de classe é mostrado aqui no corpo. É acessível através do seguinte código:
Os atributos são retornados no formato de sequência e podem ser inconsistentes de navegador para navegador. No entanto, eles podem ser vitais em algumas situações. Como exemplificado acima, o IE 8 Quirks Mode (e abaixo) espera o nome de uma propriedade DOM em get / set / removeAttribute em vez do nome do atributo. Essa é uma das muitas razões pelas quais é importante saber a diferença.
Propriedades do DOM
Sintaxe:
document.body.onload = foo;
Objetivo: fornece acesso às propriedades que pertencem aos nós do elemento. Essas propriedades são semelhantes aos atributos, mas são acessíveis apenas por JavaScript. Essa é uma diferença importante que ajuda a esclarecer o papel das propriedades do DOM. Observe que os atributos são completamente diferentes das propriedades , pois essa atribuição do manipulador de eventos é inútil e não receberá o evento (o corpo não possui um evento onload, apenas um atributo onload).
Visualização:
Aqui, você verá uma lista de propriedades na guia "DOM" no Firebug. Essas são propriedades do DOM. Você notará imediatamente alguns deles, pois você os teria usado antes sem saber. Seus valores são o que você receberá por meio de JavaScript.
Documentação
Exemplo
HTML:
<textarea id="test" value="foo"></textarea>
JavaScript:
alert($('#test').attr('value'));
Nas versões anteriores do jQuery, isso retorna uma string vazia. Em 1.6, ele retorna o valor adequado
foo
,.Sem ter examinado o novo código para qualquer função, posso dizer com confiança que a confusão tem mais a ver com a diferença entre atributos HTML e propriedades DOM, do que com o próprio código. Felizmente, isso esclareceu algumas coisas para você.
-Matt
fonte
$.prop()
obtém propriedades DOM,$.attr()
obtém atributos HTML. Estou tentando preencher a lacuna psicologicamente para que você possa entender a diferença entre os dois.$('#test').prop('value')
não retorna nada? Nem.attr('checked')
para uma caixa de seleção? Mas costumava? Agora você teria que mudar paraprop('checked')
? Não compreendo a necessidade dessa distinção - por que é importante diferenciar entre atributos HTML e propriedades DOM? Qual é o caso de uso comum que fez essa alteração "há muito tempo" ? O que há de errado em abstrair a distinção entre os dois, já que parece que seus casos de uso se sobrepõem principalmente?value
é um dos casos mais óbvios, pois avalue
propriedade fornecerá o valor atual de um campo, mas ovalue
atributo fornecerá o valor original que foi declarado novalue="..."
atributo, que é realmente odefaultValue
propriedade. (Embora neste caso particular fica confuso novamente por bugs no IE <9.)attr('value', ...)
no jQuery <1.6 define a propriedade, portanto o valor atual é alterado e o valor padrão não. Na versão 1.6, ele define o atributo; portanto, em teoria, o valor padrão muda e o valor atual não. No entanto, existem (mais) inconsistências no navegador sobre o que exatamente define ovalue
atributo. No IE, também define o valor atual; em alguns navegadores, apenas define o valor atual se o valor atual ainda não tiver sido definido antes. [chora]Uma propriedade está no DOM; um atributo está no HTML que é analisado no DOM.
Maiores detalhes
Se você alterar um atributo, a alteração será refletida no DOM (às vezes com um nome diferente).
Exemplo: Alterar o
class
atributo de uma tag altera aclassName
propriedade dessa tag no DOM. Se você não tiver nenhum atributo em uma tag, ainda terá a propriedade DOM correspondente com um valor vazio ou padrão.Exemplo: enquanto sua tag não tem
class
atributo, a propriedade DOMclassName
existe com um valor de sequência vazio.editar
Se você alterar um, o outro será alterado por um controlador e vice-versa. Este controlador não está no jQuery, mas no código nativo do navegador.
fonte
jQuery('p').prop('className', 'foo');
no console do Chrome e você verá como todos os parágrafos recebem oclass
atributo thg'foo'
. Claro que não no código fonte, que vem do servidor. Isso é uma constante.É apenas a distinção entre atributos HTML e objetos DOM que causa confusão. Para aqueles que se sentem à vontade atuando nas propriedades nativas dos elementos DOM, como
this.src
this.value
this.checked
etc,.prop
é uma recepção calorosa à família. Para outros, é apenas uma camada adicional de confusão. Vamos esclarecer isso.A maneira mais fácil de ver a diferença entre
.attr
e.prop
é o seguinte exemplo:$('input').attr('blah')
: retorna'hello'
conforme o esperado. Não há surpresas aqui.$('input').prop('blah')
: retornaundefined
- porque está tentando fazer[HTMLInputElement].blah
- e não existe essa propriedade nesse objeto DOM. Existe apenas no escopo como um atributo desse elemento, ou seja,[HTMLInputElement].getAttribute('blah')
Agora, mudamos algumas coisas assim:
$('input').attr('blah')
: retorna'apple'
eh? Por que não "pêra", como foi definido por último nesse elemento. Como a propriedade foi alterada no atributo de entrada, não no próprio elemento de entrada do DOM - eles basicamente quase funcionam independentemente um do outro.$('input').prop('blah')
: retorna'pear'
O que você realmente precisa ter cuidado é simplesmente não misturar o uso deles para a mesma propriedade em todo o aplicativo pelo motivo acima.
Veja um violino demonstrando a diferença: http://jsfiddle.net/garreh/uLQXc/
.attr
vs.prop
:Rodada 1: estilo
.attr('style')
- retorna estilos embutidos para o elemento correspondente, ou seja"font:arial;"
.prop('style')
- retorna um objeto de declaração de estilo, ou sejaCSSStyleDeclaration
Rodada 2: valor
.attr('value')
- retorna'hello'
*.prop('value')
- retorna'i changed the value'
* Nota: o jQuery, por esse motivo, possui um
.val()
método que internamente é equivalente a.prop('value')
fonte
TL; DR
Use em
prop()
excessoattr()
na maioria dos casos.Uma propriedade é o estado atual do elemento de entrada. Um atributo é o valor padrão.
Uma propriedade pode conter itens de diferentes tipos. Um atributo pode conter apenas cadeias
fonte
prop() and when to go for attr()
. à espera da resposta :)Verificação suja
Este conceito fornece um exemplo em que a diferença é observável: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty
Experimente:
prop
caixa de seleção foi marcada. BANG!Para alguns atributos como
disabled
onbutton
, adicionar ou remover o atributo contentdisabled="disabled"
sempre alterna a propriedade (chamada atributo IDL em HTML5) porque http://www.w3.org/TR/html5/forms.html#attr-fe-disabled diz:portanto, você pode se safar, embora seja feio, pois modifica o HTML sem necessidade.
Para outros atributos como
checked="checked"
oninput type="checkbox"
, as coisas quebram porque, quando você clica nele, ele fica sujo e, em seguida, adicionando ou removendo ochecked="checked"
atributo content não alterna mais a verificação .É por isso que você deve usar principalmente
.prop
, pois afeta diretamente a propriedade efetiva, em vez de depender de efeitos colaterais complexos da modificação do HTML.fonte
checked
atributo:checked="checked"
Tudo está no documento :
Então use prop!
fonte
$.attr()
recuperando propriedades na maioria das vezes em que trabalhei com ela, não "às vezes". A confusão causada por isso ainda é ressonante hoje. Infelizmente, estou tendo muitos problemas para encontrar uma leitura definitiva sobre atributos HTML versus propriedades DOM, portanto, talvez eu escreva uma resposta aqui daqui a pouco.atributos estão no seu documento / arquivo de texto HTML (== imagine que este é o resultado da sua marcação html analisada), enquanto as
propriedades estão na árvore HTML DOM (== basicamente uma propriedade real de algum objeto no sentido JS).
É importante ressaltar que muitos deles são sincronizados (se você atualizar a
class
propriedade, oclass
atributo em html também será atualizado; caso contrário). Mas alguns atributos podem ser sincronizados com propriedades inesperadas - por exemplo, atributochecked
corresponde à propriedadedefaultChecked
, para que.prop('checked')
valor, mas não mudará.attr('checked')
e.prop('defaultChecked')
valores$('#input').prop('defaultChecked', true)
também será alterada.attr('checked')
, mas isso não será visível em um elemento.E aqui está uma tabela que mostra onde
.prop()
é preferido (mesmo que.attr()
ainda possa ser usado).Por que você às vezes deseja usar .prop () em vez de .attr (), onde este último é oficialmente recomendado?
.prop()
pode retornar qualquer tipo - string, número inteiro, booleano; while.attr()
sempre retorna uma string..prop()
é dito ser cerca de 2,5 vezes mais rápido que.attr()
.fonte
$('#myImageId').prop('src', 'http://example.com/img.png')
,var class = $('.myDivClass').prop('class')
ou$('#myTextBox').prop('type', 'button')
. E assim por diante ....prop()
funciona bem com todas as propriedades. Você não quer marcar todas as propriedades na.prop()
coluna, quer?.prop()
é preferível (embora.attr()
ainda pode ser usado) '.attr()
para definir um evento que.prop()
não pode. Como esta:$('.myDiv').attr('onclick', 'alert("Hello world!")')
. Se você mudar.attr()
para.prop()
, não funcionará. Totalmente, acho que não há razão para usar.attr()
para definir ou obter valorid/class/href/checked/src.....
. Observe que eu não digo que você está errado..attr()
:.prop()
:fonte
Normalmente você vai querer usar propriedades. Use atributos apenas para:
<input value="abc">.
fonte
attributes
-> HTMLproperties
-> DOMfonte
attirbutes
também uma das propriedades deDOM
Antes do jQuery 1.6, o
attr()
método algumas vezes considerava os valores das propriedades ao recuperar atributos, isso causava um comportamento inconsistente.A introdução do
prop()
método fornece uma maneira de recuperar explicitamente os valores das propriedades, enquanto.attr()
recupera atributos.Os documentos:
jQuery.attr()
Obtenha o valor de um atributo para o primeiro elemento no conjunto de elementos correspondentes.jQuery.prop()
Obtenha o valor de uma propriedade para o primeiro elemento no conjunto de elementos correspondentes.fonte
Lembrete delicado sobre o uso
prop()
, exemplo:A função acima é usada para verificar se a caixa de seleção1 está marcada ou não, se marcada: return 1; caso contrário: retorne 0. Função prop () usada aqui como uma função GET.
A função acima é usada para definir a caixa de seleção1 a ser marcada e retornar SEMPRE 1. Agora, a função prop () é usada como uma função SET.
Não estrague tudo.
P / S: Ao verificar a propriedade Image src . Se o src estiver vazio, prop retornará a URL atual da página (incorreta) e attr retornará uma string vazia (direita).
fonte
<img src="smiley.gif" alt="Smiley face" width="42" height="42" onclick="alert($(this).prop('src'))">
. Deve funcionar e retornar o local da imagem.Uma coisa
.attr()
pode fazer isso.prop()
não pode: afetar seletores CSSAqui está um problema que não vi nas outras respostas.
Seletor CSS
[name=value]
.attr('name', 'value')
.prop('name', 'value')
.prop()
afeta apenas alguns seletores de atributosinput[name]
(obrigado @TimDown ).attr()
afeta todos os seletores de atributosinput[value]
input[naame]
span[name]
input[data-custom-attribute]
(nenhum deles.data('custom-attribute')
afetará esse seletor)fonte
Principalmente, queremos usar o objeto DOM em vez de atributos personalizados, como
data-img, data-xyz
.Também algumas das diferenças ao acessar
checkbox
valor ehref
comattr()
eprop()
como coisa mudam com a saída DOM comprop()
o link completo deorigin
e oBoolean
valor para a caixa de seleção(pre-1.6)
Só podemos acessar elementos DOM com
prop
outros, então ele forneceundefined
Mostrar snippet de código
fonte
Existem mais algumas considerações em prop () vs attr ():
selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked e defaultSelected..etc devem ser recuperados e configurados com o método .prop (). Estes não têm atributos correspondentes e são apenas propriedades.
Caixa de seleção Para tipo de entrada
O método prop retorna o valor booleano para verificado, selecionado, desativado, readOnly..etc while attr retorna a sequência definida. Portanto, você pode usar diretamente .prop ('marcado') na condição if.
.attr () chama .prop () internamente, portanto o método .attr () será um pouco mais lento do que acessá-los diretamente por meio de .prop ().
fonte
A resposta de Gary Hole é muito relevante para resolver o problema se o código for escrito dessa maneira
Como a função prop retorna o
CSSStyleDeclaration
objeto, o código acima não funcionará corretamente em alguns navegadores (testado comIE8 with Chrome Frame Plugin
no meu caso).Assim, alterando-o para o seguinte código
resolveu o problema.
fonte