星期六, 9月 22, 2012

讓 jQuery Mobile 頁面上的固定式頁首與頁尾工具列不會因碰觸畫面而隱藏

有朋友今天傳了一個 jQuery Mobile 的頁面給我, 程式如下:
<!DOCTYPE html> 
<html>
<head>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1"> 
 <title>jQuery Mobile Demo</title> 
 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" />
 <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
 <script type="text/javascript">
 $(document).bind("mobileinit", function(){
  $("[data-role=header],[data-role=footer]").fixedtoolbar({ tapToggle:false });
 });
 </script>
 <script src="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js"></script>
</head> 

<body> 
<div data-role="page">
 <div data-role="header" data-position="fixed" data-fullscreen="true">
  <h1>全螢幕標頭</h1>
 </div>
 <div data-role="content">
  <img src="mycat.jpg" /> 
 </div>
</div>
</body>
</html>
這個程式是希望能在初始化的階段透過第 11 行的程式設定固定在頁首與頁尾的工具列不會因為使用者碰觸畫面而自動隱藏或重現, 不過實際執行之後, 發現設定失效, 工具列還是會以預設的方式自動隱藏或重現。經過查詢 jQuery Mobile 文件以及 Google 爬文後, 發現 mobileinit 事件發生時, 其實後續的 HTML 內容並未載入, 因此事件處理方法中的 $("[data-role=header],[data-role=footer]") 根本就抓不到元素, 自然無法讓期望的設定生效。為了解決這個問題, 只要改成處理 pageinit 事件, 也就是在後續的 HTML 內容生成後再進行設定, 就可以正確執行了。修改的程式如下:
$(document).bind("pageinit", function(){
 $("[data-role=header],[data-role=footer]").fixedtoolbar({ tapToggle:false });
});
你也可以在事件處理的程式中多加上一行 alert() 呼叫, 就可以觀察實際抓取到的元素內容了:
$(document).bind("pageinit", function(){
 $("[data-role=header],[data-role=footer]").fixedtoolbar({ tapToggle:false });
 alert($("[data-role=header],[data-role=footer]").text());
});

9 則留言:

小包 提到...

你這一招實在是太有用,在根本上解決了問題,在沒發現你這篇文章之前我在網路上尋找好久,自己嘗試後發現幾個解法

解法一,將這段script加入網頁中,但副作用是如果當畫面上的資料超過你的螢幕一頁以上時,點擊比如說下拉式選單或是INPUT內容(表單內的元素),上下工具欄又收起來了,一整個詭異的狀況
$.mobile.fixedtoolbar.prototype.options.tapToggle = false; //jquery mobile點擊空白區域頭部和底部會消失,所以得把這個效果關掉

解法二,撰寫語法,當只要發生點擊的情況時,把工具欄上的ui-fixed-hidden強迫拿掉,因為就是這個元素在搞鬼,但實際上測試,要連點兩次時在表單元素上連點兩次後才會發生功用,縱使如此,還是有些副作用
$(function()
{
$('body').on('click', function (e)
{
//$("[data-role='header']").removeClass('ui-fixed-hidden');
});
});

解法三,在標籤上再加上,誠如解法二,還是有點副作用=>style="position:fixed"
div data-id="header" data-position="fixed" data-role="header" data-theme="b" style="position:fixed"

總之你這招是最好的,但我發現有一個小副作用,但這是可以用讀取其它新頁的方式避免的,當在同個頁面使用href="#page2"這種語法讀取同頁的其他區段時,會發生被畫面卡掉的情況
www.littlebau.com/little.gif

meebox 提到...

能幫倒忙真好, 自己沒有全面測試過, 只是大概確認解決了原本朋友的問題而已!

小包 提到...

真的謝謝您XD
我將您解決的方式也PO在我常問問題的一個地方
http://www.e-happy.com.tw/indexforum.asp?bid=11780

但由於忠於原著,還是最後把解的方式再導引回您的網頁了

meebox 提到...

沒問題。

小包 提到...

您好,我是之前請教您問題的小包
最近發現該語法
$("[data-role=header],[data-role=footer]").fixedtoolbar({ tapToggle:false });
似乎在最新版的jQuery Mobile當中,官方把fixedtoolbar這個function拿掉了耶
http://code.jquery.com/mobile/latest/jquery.mobile.min.js
它這個是1.4.0pre,2013-06-04T13:17:51Z的版本
因此若該語法搭配此js會發生頁面跟本無法產生出來的錯誤,我知道pre的版本只能當作參考,但它現在拿掉一定有什麼樣的原因,能提供給我一點意見嗎

我這邊還保留稍早之前的舊一點點的版本
http://www.littlebau.com/sample2_do/js/jquery.mobile.min.js
它這個是1.4.0pre,2013-04-30T15:09:18Z的版本
用這個就OK

meebox 提到...

我建議等他真的 release 再處理, 而且也不一定要用最新的版本。另外, 在這個 demo 頁面 (http://api.jquerymobile.com/fixedtoolbar/), 最下方的展示中頁首的工具列不會自動隱藏, 但是從 demo 程式碼中卻看不到有額外用 JS 處理, 不知道是不是第 14 行有兩層 header 的關係, 我還沒有時間去研究, 也許你可以測試看看?

小包 提到...
作者已經移除這則留言。
小包 提到...

後來發現一招,經過我手機跟平版的測試,只要在你的header跟footer上加上此一屬性,其效果同等於你那段script唷
data-tap-toggle="false"
分享給您,或許有一天可以派得上用場
新舊版js皆適用唷

meebox 提到...

感謝, 我想我會用得到喔!