移動端如何強制頁面橫屏

来源:http://www.cnblogs.com/wwhhq/archive/2017/12/19/8067723.html
-Advertisement-
Play Games

背景 最近公司要開發一個移動端的類網頁游戲: 長按按鈕有個自行車一直騎行,碰到某個國家的地標就彈出該國的相應say hello的tip,要求橫屏顯示,不能豎屏。 然而當用戶豎屏打開時,而且沒開啟手機里的橫屏模式,還要逼用戶去開啟。這時候用戶早就不耐煩的把你的游戲關掉了。 而且有些機型有些app不能橫 ...


背景

最近公司要開發一個移動端的類網頁游戲: 長按按鈕有個自行車一直騎行,碰到某個國家的地標就彈出該國的相應say hello的tip,要求橫屏顯示,不能豎屏。

然而當用戶豎屏打開時,而且沒開啟手機里的橫屏模式,還要逼用戶去開啟。這時候用戶早就不耐煩的把你的游戲關掉了。

而且有些機型有些app不能橫屏:比如Android的微信就沒有橫屏模式,而ios的微信能開啟橫屏模式。

解決辦法就是在豎屏模式下,寫一個橫屏的div,然後設置rotate正(負)90度,把他旋轉過來;而且如果用戶切到橫屏時,需要把rotate複原,要求也能正常展現。

純css

把main這個div在豎屏模式下橫過來,橫屏狀態下不變。

@media screen and (orientation: portrait) {
    .main {
        -webkit-transform:rotate(-90deg);
        -moz-transform: rotate(-90deg);
        -ms-transform: rotate(-90deg);
        transform: rotate(-90deg);
        width: 100vh;
        height: 100vh;
        /*去掉overflow 微信顯示正常,但是瀏覽器有問題,豎屏時強制橫屏縮小*/
        overflow: hidden;
    }
}

@media screen and (orientation: landscape) {
    .main {
        -webkit-transform:rotate(0);
        -moz-transform: rotate(0);
        -ms-transform: rotate(0);
        transform: rotate(0)
    }
}

但是有個問題是在橫屏模式下,利用css旋轉90度後,寬和高不好控制。

width: 100vh;
height: 100vh;

這樣控制寬高不太適合單屏寬高的頁面。

js計算寬高、對齊、旋轉

上文提到了,在portrait下,旋轉到橫屏後寬和高會有問題。可以通過下麵的js來實現。

var width = document.documentElement.clientWidth;
var height =  document.documentElement.clientHeight;
if( width < height ){
  $print =  $('#print');
  $print.width(height);
  $print.height(width);
  $print.css('top',  (height-width)/2);
  $print.css('left',  0-(height-width)/2 );
  $print.css('transform' , 'rotate(90deg)');
  $print.css('transform-origin' , '50% 50%');
}

需要註意的是transform-origin是50% 50%,旋轉90deg後,還需要重新設置top和left將其對齊。

最終方案

如果用戶手機的旋轉屏幕按鈕開著,那麼當手機橫過來之後,上面的代碼還是有問題。

var evt = "onorientationchange" in window ? "orientationchange" : "resize";
      
    window.addEventListener(evt, function() {
        console.log(evt);
        var width = document.documentElement.clientWidth;
         var height =  document.documentElement.clientHeight;
          $print =  $('#print');
         if( width > height ){
           
            $print.width(width);
            $print.height(height);
            $print.css('top',  0 );
            $print.css('left',  0 );
            $print.css('transform' , 'none');
            $print.css('transform-origin' , '50% 50%');
         }
         else{
            $print.width(height);
            $print.height(width);
            $print.css('top',  (height-width)/2 );
            $print.css('left',  0-(height-width)/2 );
            $print.css('transform' , 'rotate(90deg)');
            $print.css('transform-origin' , '50% 50%');
         }
        
    }, false);

完整代碼

/**
 * 橫豎屏
 * @param {Object}
 */
function changeOrientation($print) {  
  var width = document.documentElement.clientWidth;
  var height =  document.documentElement.clientHeight;
  if(width < height) {
      $print.width(height);
      $print.height(width);
      $print.css('top',  (height - width) / 2 );
      $print.css('left',  0 - (height - width) / 2 );
      $print.css('transform', 'rotate(90deg)');
      $print.css('transform-origin', '50% 50%');
  } 
 
  var evt = "onorientationchange" in window ? "orientationchange" : "resize";
      
      window.addEventListener(evt, function() {

      setTimeout(function() {
          var width = document.documentElement.clientWidth;
          var height =  document.documentElement.clientHeight;
          // 刷新城市的寬度
          initCityWidth();
          // 初始化每個氣泡和自行車碰撞的距離
          cityCrashDistanceArr = initCityCrashDistance();
    
        if( width > height ){
            $print.width(width);
            $print.height(height);
            $print.css('top',  0 );
            $print.css('left',  0 );
            $print.css('transform' , 'none');
            $print.css('transform-origin' , '50% 50%');
         }
         else {
          $print.width(height);
            $print.height(width);
            $print.css('top',  (height-width)/2 );
            $print.css('left',  0-(height-width)/2 );
            $print.css('transform' , 'rotate(90deg)');
            $print.css('transform-origin' , '50% 50%');
         }
    }, 300);    
   }, false);
}

總結

  • 該方案只適合頁面寬高占一屏,不適合可以滾動的方案
  • 用orientationchange和resize監聽橫豎屏切換會有延遲的問題,具體解決延遲的方案見我的另外一篇文章js實現手機橫豎屏事件

參考資料

demo

代碼

代碼

https://github.com/zuopf769/notebook/blob/master/fe/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%A6%82%E4%BD%95%E5%BC%BA%E5%88%B6%E9%A1%B5%E9%9D%A2%E6%A8%AA%E5%B1%8F/README.md


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 項目開發中,有時候我們需要將本地的文件上傳到伺服器,簡單的幾張圖片還好,但是針對iPhone裡面的視頻文件進行上傳,為了用戶體驗,我們有必要實現斷點上傳。其實也不是真的斷點,這裡我們只是模仿斷點機制。 需求 既然需要上傳文件,那最好要有一個上傳列表界面,方面用戶對上傳中的文件進行實時管理。這裡我簡單 ...
  • 一直以來,大家都苦惱怎麼實現微信公眾帳號可以接入客服,也因此很多第三方介面平臺也開發客服系統CRM系統,不過不是操作複雜就是成本太高。今天分享一個低成本又簡便的方法,讓你的公眾帳號接入QQ客服。下麵介紹具體的方法:1、首先,這個方法目前微信最新的手機版本都是適用的,測試過微信5.0安卓版本還有點問題 ...
  • 在最近的移動端佈局當中,最炙手可熱的方式便是使用rem進行元素的佈局。以下便是從最近的文章中所總結出來的一點東西。 首先,我們必須有以下的疑問: rem的本質是什麼? rem如何實現自適應佈局? 如何根據設計稿來調整rem的值? rem佈局是能純CSS還是必須JS進行輔助? 接著,我們來稍微解答或者 ...
  • JavaScript是世界上最流行的腳本語言,因為你在電腦、手機、平板上瀏覽的所有的網頁,以及無數基於HTML5的手機App,交互邏輯都是由JavaScript驅動的。 簡單地說,JavaScript是一種運行在瀏覽器中的解釋型的編程語言。 在Web世界里,只有JavaScript能跨平臺、跨瀏覽器 ...
  • 各種遍歷對象的方法返回值的不同 前置代碼: function Obj() { // 直接在this上添加屬性 this.prop_this = 'prop_this'; // 在this上添加symbol屬性 this[Symbol.for('prop_symbol')] = 'prop_symbo ...
  • 從模塊流可以看出,這個NodeWatchFileSystem模塊非常深,這裡暫時不會深入到chokidar模塊,有點太偏離本系列文章了,從WatcherManager開始講解。 流程如圖: 源碼非常簡單,包括一個工廠函數與兩個原型方法,整理如下: 包含一個容器類和三個實例方法,每一次調用watchF ...
  • 首先我們要在<body>中創建一個按鈕<button>來用作點擊創建圖片,在<button>中寫一個點擊事件(隨便命名), 在創建一個<div>存放圖片,在<div>中創建一個id(跟上面一樣隨便命名) 代碼如下: <button onclick="hehe()">創建圖片</button> <di ...
  • 個人筆記,學習JavaScript以來積累的一些常遇問題的方法和總結 不斷更新中... 轉載需註明 不引入第三個變數,調換兩個數的值 熟悉了這樣的寫法,可以少聲明一個變數 x=10;y=8; //法一: x=x y;//x=2,y=8 y=y+x;//y=10,x=2 x=y x;//x=8,y=1 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...