Is it correct to use $ (selector) .not (': visible') here?

4

I am refactoring the CSS of a system function and to treat the CSS property and not a string I changed this line of code: (from the 1st way was working correctly)

var ultimaMensagem = $("#box-confirm:not([style*='display: none;']),#box-erro:not([style*='display: none;'])").last();

for this:

var ultimaMensagem = $('#box-confirm:not(:visible),#box-erro:not(:visible)').last();

And so the code block looked like this:

GerenciadorModais.prototype.FecharModal = function () {        
        var ultimaModal = $(".modalJanela").last(); //Pegar a ultima Modal que será fechada

        //var ultimoBlock = $(".modal:not([style='display: none;'])").last(); //Maneira antiga
        var ultimoBlock = $(".modal:not(:visible)").last(); //Pegar a ultima div que será somente escondida

        //var ultimaMensagem = $("#box-confirm:not([style*='display: none;']),#box-erro:not([style*='display: none;'])").last(); //Maneira antiga
        var ultimaMensagem = $('#box-confirm:not(:visible),#box-erro:not(:visible)').last(); //Pegar a ultima div de mensagem que será somente escondida

        if (ultimoBlock.length > 0) { // Deixar invisivel essa div
            ultimoBlock.css('display', 'none'); 
        } else 
            if (ultimaMensagem.length > 0) { // Deixar invisivel essa div
                ultimaMensagem.css('display', 'none'); 
            } else { // fechar essa modal
                ultimaModal.remove(); 
                $(".block").last().remove();
                this.nivelModal--;
            }

        if (!$(".modalJanela").length > 0) //Fechar a layer escura
            $('#btn-center-dialog').fadeOut();
    };

IMAGE URL ABOVE

I took into consideration what is written in this post: link

But I'm not sure if this will bring future problems. Basically I need to get all the # box-confirm and # box-error that are invisible in some way on the screen.

So my questions are:

1) Why does not this change work? Note: I'm doing tests and I noticed that what is not working is the last else that actually closes a modal, but this is probably happening because it is trying to close one of the divs and not the modal.

2)

Is there any possibility that it will not take the last selector that is invisible on the screen?

3) Is there any better way to do this or is this already the best solution?

    
asked by anonymous 01.07.2015 / 16:38

2 answers

2

In case the correct one would not be #box-confirm:not(:visible) , but #box-confirm:visible because :not() with style*='display: none;' looks for elements visible as said by @falsarella.

: visible vs selector by attributes

Assuming that using the original and its html were:

<div style="display:none !important;">

In some browsers (if not all) the selector would not find it.

It's really best to use :visible because it checks both:

  • DOM.style.display !== "none"

  • DOM.style.visibility === "visible"

  • <input type="hidden">

  • Selector by class and performance

    Another one you can use (which can be in micro-optimization faster) would be a class:

    .hide { display:none; }
    

    This way:

    var ultimaMensagem = $('#box-confirm.hide,#box-erro.hide').last();
    

    It is faster theoretically due to only doing one check while in :visible , it can do more than one (depending on the situation).

    Note also that :visible is a jQuery selector and not a default one, so in this case jquery will not use querySelector (which is faster because it is native). Selectors per class are native.

    Note: jQuery uses querySelector (or querySelectorAll ) when the function and selector are supported, making queries faster.

        
    01.07.2015 / 16:57
    3

    Actually, :not([style*='display: none;']) should be translated to :visible , not :not(:visible) .

    After all, a no element has display: none; visible.

        
    01.07.2015 / 19:11