When using jQuery.attr() to set an attribute the browser doesn't update the style from the css

StackOverflow https://stackoverflow.com/questions/4329947

  •  29-09-2019
  •  | 
  •  

Pergunta

I have a site hat lists a set of files that can be downloaded. The custom attribute docType is set based on the file extension. If there is no extension the docType is set to "unknownDoc". The CSS file looks similar to this:

.TitleColumn[docType="pdf"]
{
    background: url("/images/common/icons/pdf.png") no-repeat left center;
}

.TitleColumn[docType="doc"], TitleColumn[docType="docx"]
{
    background: url("/images/common/icons/word.png") no-repeat left center;
}

.TitleColumn[docType="unknownDoc"]
{
    background: url("/images/common/icons/unknownDoc.png") no-repeat left center;
}

It's quite possible that a user will upload a document that we don't have a css style set up for yet. In this case the item will have a docType but no background-image. In these cases I want the unknownDoc style to be applied. So I use the following:

$('.TitleColumn').each(function (index) {
    var hasNoDocImage = $(this).css("background-image") == "none";
    var docType = $(this).attr("docType");

    if (hasNoDocImage && docType) {
        $(this).attr("docType", "unknownDoc");
        $(this).addClass("TitleColumn[docType=\"unknownDoc\"]");
    }
});

This works fine. What I don't understand is why do I have to use the addClass statement? The attr or addClass by themselves does not work. It's as if adding the attribute doesn't cause the browser to re-style the item based on the new attribute like addClass does. Is this a jQuery thing or a browser thing?

Is there a better way to do this?

I tried using just classes rather than the docType custom attribute but it gets too messy, especially when additional classes may be added to the element in the future.

Foi útil?

Solução

Seems to just be with IE as Chrome and FF work fine without the addClass. An easier version of yours above is:

$(this).attr("docType", "unknownDoc").removeClass('TitleColumn').addClass('TitleColumn');

Seems to be IE's inability (or jQuery's) to understand dynamic changes to selectors.

You can verify in this fiddle that FF and Chrome are fine: http://jsfiddle.net/fUSVF//

Outras dicas

Wouldn't it be simpler to change your css to:

.TitleColumn[docType="unknownDoc"], .unregisteredExtension
{
    background: url("/images/common/icons/unknownDoc.png") no-repeat left center;
}

And just .addClass("unregisteredExtension") after detecting this case?

   if (hasNoDocImage && docType) {
      $(this).addClass("unregisteredExtension")
   }

You are not really supposed to add custom attributes. Browsers don't have to care about them - actually, ignoring them completely is the best thing they can do so ensure if you store some crap in them it won't mess anything up.

If you want to change appearance via JavaScript+CSS, use classes. The easiest way is with an element which just has no other classes, then you can simply do $(elem).removeClass().addClass('yourNewClass');

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top