Domanda

I'm working on making a navigation bar at the bottom of the webpage (for mobile layouts), and I use jQuery to resize the navigation after the page has loaded.

I have each button as a cell in a table , and each cell contains an image. I'm trying to set the image dimensions based on the size of the element. What I have now works exactly like I want it, but I don't know why.

The source of my confusion:

$("img.nav").each(function() {
    $(this).width(); // commenting out this line changes the width of each <td> element     
    $(this).css("display", "block");
    $(this).css("height", "80%");
    $(this).css("width", "auto");
});

Here's what I get when I print the td's width:

With $(this).width(); as is:

w 0: 217
w 1: 217
w 2: 217

Which is perfect. Here's the output when I comment out that line:

w 0: 210
w 1: 200
w 2: 241

Not perfect. I need them all to be the same.

E: Also, removing the "display: none;" line in the CSS file simulates the same problem.

Here's the rest of my code (it's short):

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />

        <link rel="stylesheet" type="text/css" href="css/globals.css" />

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
        <script src="cordova.js"></script>
        <script src="js/libjs.js"></script>

        <title></title>
    </head>
    <body>
        <div id="content"><p>Some example text that does nothing.</p></div>

        <nav>
            <table>
                <tr>
                    <td id="nav_home" class="active">
                        <img class="center nav" src="img/home.png" alt="img_nav_home" width="150" height="200"/>
                    </td>

                    <td id="nav_map">
                        <img class="center nav" src="img/map.png" alt="img_nav_map" width="103" height="200"/>
                    </td>

                    <td id="nav_send">
                        <img class="center nav" src="img/send.png" alt="img_nav_send" width="286" height="200"/>
                    </td>
                </tr>
            </table>
        </nav>
    </body>
</html>

CSS:

* 
{
    padding: 0px;
    margin: 0px;
    width: 100%;
    height: 100%;
    border-style: none;
    font-family: "Berlin Sans FB", Arial, sans-serif;
    color: #383c47;

    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);  /* transparent link selection, last value opacity 0 to 1.0 */
    -webkit-touch-callout: none;                    /* prevent callout to copy image */
    -webkit-text-size-adjust: none;                 /* prevent resizing text to fit */
    -webkit-user-select: none;                      /* prevent copy paste */
}

/* Centers an image both horizontally and vertically in it's container. */
img.center {
    display: block;
    margin: auto;
}

body {
    background-image: url(../img/bg.png); 
}

#content {
    background-color: white;
    width: 70%;
    height: 70%;
}

    #content p {
        padding: 5%;
    }

/* The navigation bar at the bottom of each page. */
nav {
    background-color: #b50043;
    width: 100%;
    height: 18%;
}

    nav table {
        border-spacing: 0px;
    }

    nav table .active {
        background-color: #383c47;
    }

    nav table img.nav {     
        display: none;  /* Also, removing this line will cause the same problem */
    }

    nav table #nav_home {
        background-color: lightblue;
    }

    nav table #nav_map {
        background-color: green;
    }

    nav table #nav_send {
        background-color: blue;
    }

jQuery:

// Centers the element both vertically and horizontally in the given element.
// Allows Top and Left offsets to account for "fixed" elements in the parent.
// Does not work with images (images work a little differently).
jQuery.fn.center = function(parent, offsetTop, offsetLeft) {
    $(this).css("position", "absolute");
    $(this).css("top", ($(parent).height() - this.outerHeight()) / 2 + offsetTop);
    $(this).css("left", ($(parent).width() - this.outerWidth()) / 2 + offsetLeft);

    return $(this);
}

// Use .resize and .ready to adjust layout based on screen size
$(window).resize(function() {
    $("#content").center($(window), -($("nav").height() / 2), 0);

    // positions the navigation bar at the bottom of the page
    $("nav").css("position", "fixed");
    $("nav").css("top", $(window).height() - $("nav").height());

    // equally distribute nav buttons over the width of the screen
    $("nav table tr > td").each(function() {
        $(this).width($("nav").width() / $(this).length);
        $(this).height($("nav").height());
    }); 

    $("img.nav").each(function() {
        //$(this).width();          
        $(this).css("display", "block");
        $(this).css("height", "80%");
        $(this).css("width", "auto");
    });

    $("td").each(function(i) {
        console.log("w " + i + ": " + $(this).width());
    })

});

$(document).ready(function() {
    $(window).trigger('resize');
});

Thanks in advance!

È stato utile?

Soluzione 2

I was able to fix this by using

table-layout: fixed;

to evenly distribute the table cells rather than calculating it on page load. Not sure why I didn't think of this before.

Altri suggerimenti

You should change your call resize on on $(window).load instead of $(document).ready.

The problem is in next thing - document.ready event is fired when when HTML-Document is loaded and DOM is ready but you need to wait until all images are loaded as well.

Documentation:

onload Event

ready Event

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top