jQueryMobile显示错误的height()值

时间:2012-03-21 15:37:58

标签: javascript jquery css jquery-mobile height

我有一个非常简单的标记为jQM应用程序的主页/索引屏幕/页面:

<div id="home" class="container" data-role="page">
    <div class="grid-quarter">
        <a class="ui-link">
            <span class="grid-icon-container">
                <span class="grid-icon icon-lock"></span>
                <span class="grid-icon-text">LABEL TEXT</span>
            </span>
        </a>
    </div>
    <!-- 3 x the same -->
</div>

问题

现在在jsFiddle上运行正常,但是只要我在jQM应用程序中抛出完全相同的代码,js .height()函数(以及其他所有尝试获取元素高度)都会失败。

我编写了一个函数,可以检查任何机会确定高度,并使用jQM失败。即使我试图直接从DOM对象获取它也会失败。即使我看到DOM对象具有确切的高度设置。有趣的是:.width()输出正确。

我不知道从哪里开始调试此问题。任何帮助表示赞赏。感谢。


测试代码

// Trigger on Load and Resize 
$( '#home' ).on( 
     'pageinit'
    ,function( event )
    {
        fitIconFont( '.icon-font' );
    }
);
// Fit on Window size change
$( window ).resize( function()
{
    fitIconFont( '.icon-font' );
} );

function fitIconFont( class_name )
{
    // DEBUG
    jQuery( class_name ).each( function( index, element ) 
    {
            // WORKS:
        $( this ).on( 'click', function () 
        {
            console.log( $( this ).height() );
        } );
        console.log( $( element ).css('width') );
        console.log( $( element ).width() );

            // FAILS with 20px as output
        console.log( $( element ).css('height') );
        console.log( $( element ).height() );
        console.log( element.scrollHeight );
        console.log( element.offsetHeight );
        console.log( element.clientHeight );
        console.log( element );

        console.log( $( this ).height() );
        console.log( $( this ).css('height') );
        console.log( this.scrollHeight );
        console.log( this.offsetHeight );
        console.log( this.clientHeight );
        console.log( this );
    } );
}

Chrome开发栏

的屏幕截图

Link to jsFiddle example

3 个答案:

答案 0 :(得分:1)

当您在JSFiddle中运行此代码时,您可能没有弄乱左侧的设置以何时加载JavaScript(位于Framework选择下拉列表的正上方)。默认情况下,它设置为onLoad,这是$(window).on('load', ...)的等值。当window.load触发时,所有资产都将被正确加载和设置样式,以便您获得准确的高度。

它在click事件处理程序中工作,因为页面上的所有资源都已加载,您可以获得准确的读数。 width可能正在被正确报告,因为一旦页面完全加载它就不会改变,这是正常情况下发生的,因为块级元素默认占用100%宽度。

我尝试在JSFiddle中使用no wrap (body)设置,因此代码与我通常放置代码的位置(文档底部)同时运行。

答案 1 :(得分:1)

HTML

<div id="header">
    <h1>Header</h1>
</div>
<div id="home" data-role="page" class="container" style="background-color: #aaa;">
    <div class="grid-half " style="background-color: #009ee0;">
        <a href="#" class="ui-link">
            <span class="grid-icon-container">
                <span class="icon-font icon-a"></span>
                <span class="grid-icon-text">Label A</span>
            </span>
        </a>
    </div>
    <div class="grid-half last" style="background-color: #FF00FF;">
        <a href="#" class="ui-link">
            <span class="grid-icon-container">
                <span class="icon-font icon-b"></span>
                <span class="grid-icon-text">Label B</span>
            </span>
        </a>
    </div>
    <div class="grid-half btop" style="background-color: #FFFF00;">
        <a href="#" class="ui-link">
            <span class="grid-icon-container">
                <span class="icon-font icon-c"></span>
                <span class="grid-icon-text">Label C</span>
            </span>
        </a>
    </div> 
    <div class="grid-half last btop" style="background-color: #000;">
        <a href="#" class="ui-link">
            <span class="grid-icon-container">
                <span class="icon-font icon-d"></span>
                <span class="grid-icon-text">Label D</span>
            </span>
        </a>
    </div>       
</div>

脚本

function fitIconFont( elements ) 
{
    $( elements ).each( function( key, el )
        {
            var 
                container         = $( el ).parent()
                container_height = parseInt( $( container ).outerHeight( true ), 0 )
                new_icon_height  = parseInt( container_height * 0.75, 0 ) + 'px'
                new_label_height = parseInt( container_height * 0.25, 0 ) + 'px'
            ;

            // Set font-sizes for icon & label
            $( el ).css( 'font-size', new_icon_height );
            $( el ).next().css( 'font-size', new_label_height );

            // Debug print
            $( '#header' ).text( 'current heights: Container: ' + container_height + ' / ' );
            $( '#header' ).append( 'Icon: ' + new_icon_height + ' / ' );
            $( '#header' ).append( 'Label: ' + new_label_height );
        }
    );
}

// Trigger on Load and Resize 
// Fit on Window load
$( window ).on( 'load' )
{
    fitIconFont( '.icon-font' ) ;
}
// Fit on Window size change
$( window ).resize( function()
{
    fitIconFont( '.icon-font' );
} );

// Fit on Page Show
jQuery( '#home' ).on( 
     'pageshow'
    ,function( event )
     {
        fitIconFont( '.icon-font' );
     }
).trigger( 'updatelayout' );

// Fit on Orientation Change
jQuery( '#home' ).on( 
     'orientationchange'
    ,function( event )
     {
        fitIconFont( '.icon-font' );
     }
).trigger( 'updatelayout' );

/**
 * Update grid container height/width on change of device orientation
 */
$( '#home' ).on( 
    'orientationchange'
    ,function( e )
     {
         $( '.grid-half' ).each( function( index, el )
         {
             //if ( 'portrait' !== e.orientation )
             $( el ).width( window.innerWidth * .5 );
             $( el ).height( window.innerHeight * ( 'portrait' !== e.orientation ? .6 : .5 ) );
         } );
     }
);

CSS

body, html { 
    height: 100%; 
    margin: 0;
    padding: 0; 
    font-size: 100%;
}
#header {
    height: 10%;
    width: 100%;
    line-height: 1;
    font-weight: bold;
}
#header {
    text-align: center;
}
#home {
    width: 100%;
    height: 90%;
}
    /* Grid */
    .grid-half {
        display: table;
        position: relative;
        float: left;
        width: 49.8%;
        height: 50%;
    }
    .grid-half.last {
        border-left: 1px dashed white;
    }
    .grid-btop {
        border-top: 1px dashed white;
    }
        .grid-half .ui-link {
            display: table-cell;
            position: absolute;
            height: 100%;
            width: 100%;
            vertical-align: middle;
            text-align: center;
            text-decoration: none;
        }
        .grid-half .grid-icon-container {
            display: block;
            position: relative;
            top: 25%;
            margin: 0 auto;
            height: 50%;
            width: 50%;
            border: 1px dotted #ddd;
        }
        .grid-half .icon-font {
            margin: 0 auto;
            position: relative;
            display: block;
            height: 75%;
            width: 100%;
            background-color: #bdbddb;
        }
        .grid-icon-text {
            display: block;
            position: relative;
            height: 25%;
            width: 100%;
            margin: 1% auto 0;
            text-align: center;
            background-color: #fff;
        }

/* Icons */
[class^="icon-"]:before,
[class*=" icon-"]:before {
    font-family: Arial;
    font-weight: normal;
    display: inline-block;
    text-decoration: inherit;
    text-align: center;
}
.icon-a:before     { content: "C"; color: #FFFF00; }
.icon-b:before     { content: "M"; color: #009ee0; }
.icon-c:before     { content: "Y"; color: #000; }
.icon-d:before     { content: "K"; color: #FFFF00; }

/* Style */
#header,
a {
    color: #333;
    font-family: Helvetica, Arial, sans-serif;
    text-decoration: none;
}

示例:http://jsfiddle.net/kaiser/qAcSR/

答案 2 :(得分:0)

出于某种原因,整件事只适用于添加on( 'pageinit' ) AND ( document ).ready()

不知道为什么,但这种方式可以在桌面和移动设备上触发。有趣的是:如果我只使用其中之一:Nada,没有,nix可以工作。