Bagaimana cara mengunci orientasi ke mode potret di Aplikasi Web iPhone?

160

Saya sedang membangun Aplikasi Web iPhone dan ingin mengunci orientasi ke mode potret. apakah ini mungkin? Apakah ada ekstensi web-kit untuk melakukan ini?

Harap dicatat ini adalah aplikasi yang ditulis dalam HTML dan JavaScript untuk Mobile Safari, BUKAN aplikasi asli yang ditulis dalam Objective-C.

Kevin
sumber
1
Seluruh alasan untuk membangun aplikasi web dan bukan aplikasi asli adalah agar bisa lintas platform, mengapa Anda membangun aplikasi web khusus iPhone, apakah Anda ingin menulis kode tambahan untuk mengunci ponsel lain ???
1
Saya tertarik pada solusi yang untuk "layar kecil" dan tidak hanya untuk hal-hal yang 320px dan dibuat oleh apel.
sheriffderek

Jawaban:

70

Anda dapat menentukan gaya CSS berdasarkan orientasi viewport: Targetkan browser dengan body [orient = "landscape"] atau body [orient = "portrait"]

http://www.evotech.net/blog/2007/07/web-development-for-the-iphone/

Namun...

Pendekatan Apple untuk masalah ini adalah untuk memungkinkan pengembang untuk mengubah CSS berdasarkan perubahan orientasi tetapi tidak untuk mencegah orientasi ulang sepenuhnya. Saya menemukan pertanyaan serupa di tempat lain:

http://ask.metafilter.com/99784/How-can-I-lock-iPhone-orientation-in-Mobile-Safari

Scott Fox
sumber
Terima kasih tetapi, saya sudah melakukan bagian itu, yang saya inginkan adalah mencegah Mobile Safari untuk tidak mengubah orientasi saya ketika pengguna memiringkan ponsel.
Kevin
4
Pendekatan Apple untuk masalah ini untuk memungkinkan pengembang untuk mengubah CSS berdasarkan perubahan orientasi tetapi tidak untuk mencegah orientasi ulang sepenuhnya. Saya menemukan pertanyaan serupa di tempat lain: ask.metafilter.com/99784/…
Scott Fox
2
Saya telah melihat beberapa situs menampilkan pesan hanya lanskap yang menginstruksikan pengguna bahwa situs ini hanya dapat dilihat dalam orientasi potret - hanya opsi lain yang perlu Anda pertimbangkan.
Jayden Lawson
97

Ini adalah solusi yang cukup rumit, tetapi setidaknya sesuatu (?). Idenya adalah menggunakan transformasi CSS untuk memutar konten halaman Anda ke mode potret semu. Berikut ini kode JavaScript (dinyatakan dalam jQuery) untuk membantu Anda memulai:

$(document).ready(function () {
  function reorient(e) {
    var portrait = (window.orientation % 180 == 0);
    $("body > div").css("-webkit-transform", !portrait ? "rotate(-90deg)" : "");
  }
  window.onorientationchange = reorient;
  window.setTimeout(reorient, 0);
});

Kode mengharapkan seluruh isi halaman Anda untuk hidup di dalam div tepat di dalam elemen tubuh. Ini memutar div 90 derajat dalam mode lansekap - kembali ke potret.

Dibiarkan sebagai latihan untuk pembaca: div berputar di sekitar titik tengahnya, sehingga posisinya mungkin perlu disesuaikan kecuali itu persegi sempurna.

Juga, ada masalah visual yang tidak menarik. Ketika Anda mengubah orientasi, Safari berputar perlahan, kemudian div tingkat atas terkunci hingga 90 derajat berbeda. Untuk lebih menyenangkan, tambahkan

body > div { -webkit-transition: all 1s ease-in-out; }

ke CSS Anda. Ketika perangkat berputar, maka Safari melakukannya, kemudian konten halaman Anda. Memperdulikan!

Grumdrig
sumber
3
Grumdrig, kau adalah pahlawanku! Ini adalah tip terkait aplikasi web iPhone yang paling berguna dan berfungsi yang pernah saya lihat di situs ini. Terima kasih banyak!
noober
Sebelum saya membaca jawaban ini, saya akan menyarankan komentar jawaban "diterima" bahwa seseorang ELSE harus mencoba ini dan memberi tahu saya jika itu berhasil. Saya sangat senang seseorang sudah melakukannya, dan itu berhasil!
Lane
bagaimana jika div adalah persegi panjang? apa rumus untuk mengatur asal transformasi dengan benar? TA
superjos
Anda juga dapat mengontrolnya dengan opsi "Orientasi Antarmuka yang Didukung" pada xCode, di bawah info pengembangan Iphone / iPod. Bekerja dengan baik
Rodrigo Dias
1
tidak bisakah kita memutar tubuhnya sendiri secara langsung? Katakanlah, $ ("body"). Css ("- webkit-transform",! Portrait? "Rotate (-90deg)": "");
Krsna Chaitanya
39

Jawaban ini belum memungkinkan, tetapi saya mempostingnya untuk "generasi masa depan". Semoga suatu hari kita dapat melakukan ini melalui aturan CSS @viewport:

@viewport {
    orientation: portrait;
}

Berikut adalah halaman "Dapatkah Saya Menggunakan" (pada 2019 hanya IE dan Edge):
https://caniuse.com/#feat=mdn-css_at-rules_viewport_orientation

Spec (dalam proses penulisan):
https://drafts.csswg.org/css-device-adapt/#orientation-desc

MDN:
https://developer.mozilla.org/en-US/docs/Web/CSS/@viewport/orientation

Berdasarkan tabel kompatibilitas browser MDN dan artikel berikut ini, sepertinya ada beberapa dukungan di versi IE dan Opera tertentu:
http://menacingcloud.com/?c=cssViewportOrMetaTag

Spesifikasi JS API ini juga terlihat relevan:
https://w3c.github.io/screen-orientation/

Saya berasumsi bahwa karena itu mungkin dengan @viewportaturan yang diusulkan , bahwa itu akan mungkin dengan menetapkan orientationdalam pengaturan viewport dalam sebuah metatag, tetapi sejauh ini saya tidak berhasil.

Jangan ragu untuk memperbarui jawaban ini ketika semuanya membaik.

xdhmoore
sumber
Pada 10/2019, fitur baru ini belum berfungsi. Tolong teruskan kami. Terima kasih.
RainCast
2
Memang sudah lama sekali saya bertanya-tanya apakah itu akan pernah terjadi. Saya telah menambahkan tautan ke halaman "CanIUse".
xdhmoore
Terima kasih. apakah Anda pemilik fitur ini? Saya tidak begitu mengerti bagaimana fitur css baru dirilis. Dalam dugaan saya, css org berbicara dengan masing-masing pemilik produk browser utama, dan meminta mereka untuk mendukungnya? Siapa yang mengendalikan proses? Aku sangat penasaran.
RainCast
Ha bukan sekadar pengembang. Anda sedang mencari W3C.
xdhmoore
19

Kode berikut digunakan di game html5 kami.

$(document).ready(function () {
     $(window)    
          .bind('orientationchange', function(){
               if (window.orientation % 180 == 0){
                   $(document.body).css("-webkit-transform-origin", "")
                       .css("-webkit-transform", "");               
               } 
               else {                   
                   if ( window.orientation > 0) { //clockwise
                     $(document.body).css("-webkit-transform-origin", "200px 190px")
                       .css("-webkit-transform",  "rotate(-90deg)");  
                   }
                   else {
                     $(document.body).css("-webkit-transform-origin", "280px 190px")
                       .css("-webkit-transform",  "rotate(90deg)"); 
                   }
               }
           })
          .trigger('orientationchange'); 
});
Andrei Schneider
sumber
bagaimana Anda mengetahui angka-angka itu untuk transformasi asal?
superjos
3
Peringatan!!! Tidak semua perangkat melaporkan nilai yang sama untuk orientasi sehingga tidak dapat diandalkan pada matthewgifford.com/blog/2011/12/22/…
Rob
6

Saya datang dengan metode hanya CSS ini memutar layar menggunakan permintaan media. Kueri didasarkan pada ukuran layar yang saya temukan di sini . 480px tampaknya baik karena tidak ada / beberapa perangkat memiliki lebar lebih dari 480px atau kurang dari 480px.

@media (max-height: 480px) and (min-width: 480px) and (max-width: 600px) { 
    html{
        -webkit-transform: rotate(-90deg);
           -moz-transform: rotate(-90deg);
            -ms-transform: rotate(-90deg);
             -o-transform: rotate(-90deg);
                transform: rotate(-90deg);
        -webkit-transform-origin: left top;
           -moz-transform-origin: left top;
            -ms-transform-origin: left top;
             -o-transform-origin: left top;
                transform-origin: left top;
        width: 320px; /*this is the iPhone screen width.*/
        position: absolute;
        top: 100%;
            left: 0
    }
}
Tagihan
sumber
+1 solusi bagus. Saya punya catatan kaki yang posisinya tetap di bawah. Adakah yang tahu bagaimana menampilkannya setelah rotasi?
Cybrix
1
Bagaimana dengan menggunakan (orientasi: lanskap) dalam kueri media alih-alih nilai piksel tertentu? Atau apakah nilai piksel yang tepat perlu ditentukan?
Justin Putney
Saya menggunakan nilai piksel karena Anda harus menetapkan nilai tepat pada html, yang harus cocok dengan tinggi layar (saat dalam lanskap - jadi lebar layar). Jadi menggunakan orientation: landscapetidak akan bekerja dengan baik dalam contoh saya @JustinPutney
Bill
1
Dari MDN: "Catatan: Nilai ini tidak sesuai dengan orientasi perangkat yang sebenarnya. Membuka keyboard lunak pada sebagian besar perangkat dalam orientasi potret akan menyebabkan viewport menjadi lebih lebar daripada tingginya, sehingga menyebabkan browser menggunakan gaya lansekap alih-alih potret. "
sheriffderek
2
Orientasi @media aturan --- yeah. Mengira mereka adalah cara untuk pergi sampai saya membaca ini: developer.mozilla.org/en-US/docs/Web/Guide/CSS/…
sheriffderek
2

Mungkin di masa depan yang baru ia akan memiliki solusion ...

Adapun Mei 2015,

ada fungsi eksperimental yang melakukan itu.

Tapi itu hanya berfungsi di Firefox 18+, IE11 +, dan Chrome 38+.

Namun, ini belum berfungsi di Opera atau Safari.

https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation#Browser_compatibility

Berikut adalah kode saat ini untuk browser yang kompatibel:

var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;

lockOrientation("landscape-primary");
Fabio Nolasco
sumber
Saya menggunakannya dalam kode javascript saya di situs wordpress saya sebagai: screen.lockOrientation ("landscape"); dan itu tidak berhasil. Saya mendapatkan: jQuery (...). LockOrientation bukan fungsi. Apakah saya perlu menerapkan plugin atau kerangka kerja apa pun?
Alex Stanese
1

Meskipun Anda tidak dapat mencegah perubahan orientasi agar tidak berlaku, Anda dapat meniru tidak ada perubahan sebagaimana dinyatakan dalam jawaban lain.

Pertama-tama deteksi orientasi atau reorientasi perangkat dan, menggunakan JavaScript, tambahkan nama kelas ke elemen pembungkus Anda (dalam contoh ini saya menggunakan tag tubuh).

function deviceOrientation() {
  var body = document.body;
  switch(window.orientation) {
    case 90:
      body.classList = '';
      body.classList.add('rotation90');
      break;
    case -90:
      body.classList = '';
      body.classList.add('rotation-90');
      break;
    default:
      body.classList = '';
      body.classList.add('portrait');
      break;
  }
}
window.addEventListener('orientationchange', deviceOrientation);
deviceOrientation();

Kemudian jika perangkat lanskap, gunakan CSS untuk mengatur lebar badan ke tinggi viewport dan tinggi tubuh ke lebar viewport. Dan mari kita atur transformasi asal saat kita berada di sana.

@media screen and (orientation: landscape) {
  body {
    width: 100vh;
    height: 100vw;
    transform-origin: 0 0;
  }
}

Sekarang, reorientasi elemen tubuh dan geser (terjemahkan) ke posisi.

body.rotation-90 {
  transform: rotate(90deg) translateY(-100%);
}
body.rotation90 {
  transform: rotate(-90deg) translateX(-100%);
}
Reggie Pinkham
sumber
0
// CSS hack to prevent layout breaking in landscape
// e.g. screens larger than 320px  
html {
  width: 320px;
  overflow-x: hidden;
}

Ini, atau solusi CSS serupa, setidaknya akan mempertahankan tata letak Anda jika itu yang Anda cari.

Solusi root adalah memperhitungkan kemampuan perangkat daripada berusaha membatasi mereka. Jika perangkat tidak memungkinkan Anda membatasi yang tepat daripada peretasan sederhana adalah pilihan terbaik karena desain pada dasarnya tidak lengkap. Semakin sederhana semakin baik.

dgoldston
sumber
0

Dalam kopi jika ada yang membutuhkannya.

    $(window).bind 'orientationchange', ->
        if window.orientation % 180 == 0
            $(document.body).css
                "-webkit-transform-origin" : ''
                "-webkit-transform" : ''
        else
            if window.orientation > 0
                $(document.body).css
                    "-webkit-transform-origin" : "200px 190px"
                    "-webkit-transform" : "rotate(-90deg)"
            else
                $(document.body).css
                    "-webkit-transform-origin" : "280px 190px"
                    "-webkit-transform" : "rotate(90deg)"
Philip
sumber
0

Terinspirasi dari jawaban @ Grumdrig, dan karena beberapa instruksi yang digunakan tidak akan berfungsi, saya menyarankan skrip berikut jika diperlukan oleh orang lain:

    $(document).ready(function () {

      function reorient(e) {
        var orientation = window.screen.orientation.type;
        $("body > div").css("-webkit-transform", (orientation == 'landscape-primary' || orientation == 'landscape-secondary') ? "rotate(-90deg)" : "");
      }
    $(window).on("orientationchange",function(){
        reorient();
    });
      window.setTimeout(reorient, 0);
    });
Yazid Erman
sumber
0

Saya memiliki masalah yang serupa, tetapi untuk membuat lansekap ... Saya percaya kode di bawah ini harus melakukan trik:

//This code consider you are using the fullscreen portrait mode
function processOrientation(forceOrientation) {
  var orientation = window.orientation;
  if (forceOrientation != undefined)
    orientation = forceOrientation;
  var domElement = document.getElementById('fullscreen-element-div');
  switch(orientation) {
    case 90:
      var width = window.innerHeight;
      var height = window.innerWidth;
      domElement.style.width = "100vh";
      domElement.style.height = "100vw";
      domElement.style.transformOrigin="50% 50%";
      domElement.style.transform="translate("+(window.innerWidth/2-width/2)+"px, "+(window.innerHeight/2-height/2)+"px) rotate(-90deg)";
      break;
    case -90:
      var width = window.innerHeight;
      var height = window.innerWidth;
      domElement.style.width = "100vh";
      domElement.style.height = "100vw";
      domElement.style.transformOrigin="50% 50%";
      domElement.style.transform="translate("+(window.innerWidth/2-width/2)+"px, "+(window.innerHeight/2-height/2)+"px) rotate(90deg)";
      break;
    default:
      domElement.style.width = "100vw";
      domElement.style.height = "100vh";
      domElement.style.transformOrigin="";
      domElement.style.transform="";
      break;
  }
}
window.addEventListener('orientationchange', processOrientation);
processOrientation();
<html>
<head></head>
<body style="margin:0;padding:0;overflow: hidden;">
  <div id="fullscreen-element-div" style="background-color:#00ff00;width:100vw;height:100vh;margin:0;padding:0"> Test
  <br>
  <input type="button" value="force 90" onclick="processOrientation(90);" /><br>
  <input type="button" value="force -90" onclick="processOrientation(-90);" /><br>
  <input type="button" value="back to normal" onclick="processOrientation();" />
  </div>
</body>
</html>

ARibeiro
sumber
-3

Klik di sini untuk tutorial dan contoh kerja dari situs web saya.

Anda tidak perlu lagi menggunakan peretasan hanya untuk melihat jQuery Mobile Screen Orientation atau Anda harus menggunakan PhoneGap lagi, kecuali Anda benar-benar menggunakan PhoneGap.

Untuk membuat ini bekerja di tahun 2015 kita perlu:

  • Cordova (versi apa pun meskipun apa pun di atas 4.0 lebih baik)
  • PhoneGap (Anda bahkan dapat menggunakan PhoneGap, plugin yang kompatibel)

Dan salah satu plugin ini tergantung pada versi Cordova Anda:

  • net.yoik.cordova.plugins.screenorientation (Cordova <4)

plugin cordova tambahkan net.yoik.cordova.plugins.screenorientation

  • plugin cordova tambahkan cordova-plugin-layar-orientasi (Cordova> = 4)

plugin cordova menambahkan cordova-plugin-layar-orientasi

Dan untuk mengunci orientasi layar cukup gunakan fungsi ini:

screen.lockOrientation('landscape');

Untuk membukanya:

screen.unlockOrientation();

Orientasi yang mungkin:

  • portrait-primary Orientasi berada dalam mode potret primer.

  • portrait-secondary Orientasi dalam mode potret sekunder.

  • landscape-primary Orientasi berada dalam mode lansekap primer.

  • landscape-secondary Orientasi dalam mode lansekap sekunder.

  • portrait Orientasi dapat berupa potret-primer atau potret-sekunder (sensor).

  • landscape Orientasinya adalah landscape-primary atau landscape-secondary (sensor).

Gajotres
sumber