admin管理员组

文章数量:1332345

I'm getting unpredictable results when calling jquery's css("display") on an element; sometimes it's flex, other times it is block. What's strange is that this error is only present when I'm using jquery's show/hide, and the error happens about 50% of the time. What's even more strange is that I'm seeing these results before hide even runs.

Update: It seems to also be tied to this google webfont css I'm including. If I remove the font the problem goes away. This is all very strange.

Here's a simplification of my code:


js:

$(document).ready(function () {
    console.log("1 display: " + $("#foo").css("display"));
    $("#foo").hide();
    console.log("2 display: " + $("#foo").css("display"));
    $("#foo").show();
    console.log("3 display: " + $("#foo").css("display"));
});

html:

<!DOCTYPE html>
<html>
    <head>
        <title>Test</title>
        <script type="text/JavaScript"
            src=".6.3.min.js"></script>
        <script type="text/JavaScript" src="script.js"></script>
        <link href='' rel='stylesheet' type='text/css'>
        <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
        <div id="foo" class="centerer">
            <p>Hello!</p>
        </div>
    </body>
</html>

css:

#foo {
    background: white url("bg.jpg") center no-repeat;
    background-size: 100vw auto;
}

.centerer {
    display: flex;
    flex-flow: column nowrap;
    align-items: center;
    justify-content: center;
}

The correct behavior should print out:

1 display: flex
2 display: none
3 display: flex

But what I'm seeing about 50% of the time is:

1 display: block
2 display: none
3 display: block

Any ideas on what could be causing this? I want to know why.

I'm getting unpredictable results when calling jquery's css("display") on an element; sometimes it's flex, other times it is block. What's strange is that this error is only present when I'm using jquery's show/hide, and the error happens about 50% of the time. What's even more strange is that I'm seeing these results before hide even runs.

Update: It seems to also be tied to this google webfont css I'm including. If I remove the font the problem goes away. This is all very strange.

Here's a simplification of my code:


js:

$(document).ready(function () {
    console.log("1 display: " + $("#foo").css("display"));
    $("#foo").hide();
    console.log("2 display: " + $("#foo").css("display"));
    $("#foo").show();
    console.log("3 display: " + $("#foo").css("display"));
});

html:

<!DOCTYPE html>
<html>
    <head>
        <title>Test</title>
        <script type="text/JavaScript"
            src="http://code.jquery./jquery-1.6.3.min.js"></script>
        <script type="text/JavaScript" src="script.js"></script>
        <link href='http://fonts.googleapis./css?family=Forum' rel='stylesheet' type='text/css'>
        <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
        <div id="foo" class="centerer">
            <p>Hello!</p>
        </div>
    </body>
</html>

css:

#foo {
    background: white url("bg.jpg") center no-repeat;
    background-size: 100vw auto;
}

.centerer {
    display: flex;
    flex-flow: column nowrap;
    align-items: center;
    justify-content: center;
}

The correct behavior should print out:

1 display: flex
2 display: none
3 display: flex

But what I'm seeing about 50% of the time is:

1 display: block
2 display: none
3 display: block

Any ideas on what could be causing this? I want to know why.

Share Improve this question edited May 2, 2015 at 11:18 Pubby asked May 2, 2015 at 10:52 PubbyPubby 53.1k13 gold badges146 silver badges185 bronze badges 4
  • show() and hide() will always result in "block" / "none". If you want flex instead you should use css classes like this: $('#foo').addClass('flex'); $('#foo').removeClass('flex').addClass('hideFlex') – Fabian Lurz Commented May 2, 2015 at 10:56
  • hide() doesn't know about flex. Wrap your #foo in a div with display:block and it should work. – thebjorn Commented May 2, 2015 at 10:59
  • @FabianLurz @thebjorn the documentation of hide claims it will save the previous display value for show to restore. Also, note how "1 display: block" gets printed before hide even gets called. – Pubby Commented May 2, 2015 at 11:02
  • Works fine in jquery 2.1.3 jsfiddle/incept0/gohn7cxs – Tech Savant Commented May 2, 2015 at 11:08
Add a ment  | 

4 Answers 4

Reset to default 1

In your bad output your initial value of display is block. This is not a bug with the show method.

Are you sure than your script is execute after the CSS calculation ?

Check your document structure :

<!DOCTYPE html>
<html>
  <head>
    <!-- css include/import -->
  </head>
  <body>
    <!-- html body -->
    <!-- script include/import -->
  </body>
</html>

For JQuery hide() and show() functions to work properly (maintain original display value) the element should be part of the DOM at the point in time when function is called. Maybe Google Webfonts temporary unloads your content from DOM...

Problem can be reproduced like this:

https://jsfiddle/u442nsko/1

#foo {
    display: flex;
}

$(document).ready(function () {

    var my = $("<div id='foo'>......</div>")
    console.log("1 display: " + my.css("display"));
    my.hide();
    console.log("2 display: " + my.css("display"));
    my.show();
    console.log("3 display: " + my.css("display"));
    $("body").append(my);
    console.log("4 display: " + my.css("display"));
});

EDIT: According to http://api.jquery./hide/ hide will save the previous state. But as it seems it is not working in your case. Solution:

js

$(document).ready(function () {
    console.log("1 display: " + $("#foo").css("display"));
    $("#foo").addClass('hideFlex');
    console.log("2 display: " + $("#foo").css("display"));
    $("#foo").removeClass('hideFlex');
    console.log("3 display: " + $("#foo").css("display"));
});

css:

   .hideFlex{
    display:none;
    }

So replace the js with my js and add .hideFlex to your css. Should work then.

Your code works in the most recent version of jquery

IMO whatever the problem is, lies with your code (maybe even the CSS) setting that display to block at some point and you are not realizing it.

JS FIDDLE

Try using addClass and removeClass. Hide and show set the value to block.

.flex {

display: flex;

}

$('selector').addClass('flex');  //show
$('selector').removeClass('flex'); //hide

本文标签: