簡單究好 Simple is Best

網頁前端開發資訊

解決JavaScript和CSS媒體查詢取得的視窗寬度不同的問題

在設計響應式網頁設計時、通常會依瀏覽器視窗的寬度指定不同的設計,包含CSS配置與JavaScript互動效果。

在CSS的世界裡判斷瀏覽器視窗寬度的方法是media query

@media (max-width: 767px)
{
    /* CSS here */
    /* 當視窗寬度小於767px時執行 */
}

在JavaScript的世界裡,則是使用 $(window).width()來檢測瀏覽器視窗的寬度:

if($(window).width() < 767)
{
    // JavaScript here 
    // 當視窗寬度小於767px時執行
} else {
    // JavaScript here
    // 當視窗寬度不小於767px時執行
}

但是透過 CSS media query 和 $(window).width()得到的寬度並不相同、二者之間有些微的落差。底下有幾個方法可以解決這個問題:

使用Modernizr.js

Modernizr.js是一個javascript的套件,可以用來檢測瀏覽器的支援性。例如:是否支援觸控動作,是否使用iOS系統…等。在底下的案例中我們要使用 Modernizr.mq()這個方法來檢測瀏覽器的視窗寬度是否符合CSS media query的條件。

var query = Modernizr.mq('(max-width: 768px)');
if (query) {
    $('#holder').html('true');
    // JavaScript here
    // 當CSS media query計算的視窗寬度小於768px時執行
} else {
    $('#holder').html('false');
    // JavaScript here
    // 當CSS media query計算的視窗寬度大於等於769px時執行
}

使用這個方法判斷的結果與使用CSS media query得到的結果一樣,這會減少很多前端開發的困擾、讓我們前端開發的工作變得更輕鬆。

要注意的是Modernizr.mq()只會在網頁載入時執行一次。如果您希望他能在每次瀏覽器視窗變動時都能再執行一次的話、您就要讓他在每次$(window).resize()時再執行一次,調整之後的javascript如下:

function mq() {
    var query = Modernizr.mq('(max-width: 768px)');
    if (query) {
        $('#holder').html('true');
        // JavaScript here
        // 當CSS media query計算的視窗寬度小於769px時執行
    } else {
        $('#holder').html('false');
        // JavaScript here
        // 當CSS media query計算的視窗寬度大於等於769px時執行
    }
};
$(window).resize(function() {
    mq();
});
mq();

使用enquire.js

enquire.js 是一個輕量的的javascript,唯一的作用就是檢測瀏覽器的視窗寬度是否符合媒體查詢的條件。使用的方法如下:

enquire.register("screen and (max-width: 768px)", {
    setup: function() {
        $('#holder').html('false');
        // JavaScript here
        // 網頁載入時執行一次
    },
    match: function() {
        $('#holder').html('true');
        // JavaScript here
        // 當CSS media query計算的視窗寬度小於769px時執行
        // 網頁載入時執行一次
        // 之後每次改變視窗時會再執行一次
    },
    unmatch: function() {
        $('#holder').html('false');
        // JavaScript here
        // 當CSS media query計算的視窗寬度大於等於769px時執行
        // 網頁載入時不會執行
        // 之後每次改變視窗時會再執行一次
    }
});

unmatch 在網頁載入時並不會被執行,這一點在使用的時候必須要注意。setup則只會在網頁載入時執行一次,因此unmatch 和setuo可以做為互補使用。

放棄使用CSS media query

如果放棄使用CSS media query又該如何設置rwd的css樣式呢?很簡單,我們使用javascript來幫符合條件的網頁添加一個樣式名稱:

function windowSize() {
    if ($(window).width() < 768) {
        $('body').addClass('mobile').removeClass('desktop');
    } else {
        $('body').addClass('desktop').removeClass('mobile');
        $('#holder').html('Desktop Size');
    }
};
$(window).resize(function() {
    windowSize();
});
windowSize();

上面的javascript用意是:當瀏覽器寬度小於768的時候、幫body添加一個名為 mobile 的樣式,反之則添加desktop。

另外在CSS的部份也要做適當的調整。

原本該是:

body {
    font-size: 36px;
}
@media (max-width: 767px) {
    p {
        color: #72D213;
    }
}
@media (min-width: 768px) {
    p {
        color: #0080ff;
    }
}

修改之後變成:

body {
    font-size: 36px;
}
body.mobile p { //當瀏覽器寬度小於768的時候
    color: #72D213; 
}
body.desktop p { //當瀏覽器寬度不小於768的時候
    color: #0080ff;
}

這樣子一來也避免掉了JavaScript和CSS media query 所取得的視窗寬度不同的問題。

 

 

 

xxxx

One Comment

Post a comment

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *