ฉันจะล็อคการวางแนวโหมดแนวตั้งในแอปพลิเคชันเว็บของ iPhone ได้อย่างไร


160

ฉันกำลังสร้างแอปพลิเคชันเว็บของ iPhone และต้องการล็อคการวางแนวเป็นโหมดแนวตั้ง เป็นไปได้ไหม มีส่วนขยายของชุดเครื่องมือทำเว็บหรือไม่

โปรดทราบว่านี่เป็นแอปพลิเคชันที่เขียนด้วย HTML และ JavaScript สำหรับ Mobile Safari ไม่ใช่แอปพลิเคชันทั่วไปที่เขียนด้วย Objective-C


1
เหตุผลทั้งหมดในการสร้างเว็บแอปพลิเคชั่นไม่ใช่แอพเนทีฟเพราะมันสามารถข้ามแพลตฟอร์มได้ทำไมคุณสร้างแอปพลิเคชั่นเว็บสำหรับ iPhone โดยเฉพาะคุณกำลังมองหาการเขียนรหัสพิเศษเพื่อล็อคโทรศัพท์อื่น ๆ

เกี่ยวข้อง: stackoverflow.com/questions/5298467/…
xdhmoore

1
ฉันสนใจวิธีแก้ปัญหาสำหรับ "หน้าจอขนาดเล็ก" และไม่เพียง แต่สำหรับสิ่งที่มีขนาด 320px และผลิตโดยแอปเปิล
sheriffderek

คำตอบ:


70

คุณสามารถระบุสไตล์ CSS ตามการวางแนววิวพอร์ต: กำหนดเป้าหมายเบราว์เซอร์ด้วย body [orient = "landscape"] หรือ body [orient = "portrait"]

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

อย่างไรก็ตาม ...

วิธีการของ Apple ในเรื่องนี้คือการอนุญาตให้นักพัฒนาเปลี่ยน CSS ตามการเปลี่ยนแปลงการวางแนว แต่ไม่ป้องกันการวางแนวใหม่ทั้งหมด ฉันพบคำถามที่คล้ายกันที่อื่น:

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


ขอบคุณ แต่ฉันทำส่วนนั้นไปแล้วสิ่งที่ฉันต้องการจริงๆคือป้องกันไม่ให้ Mobile Safari ไม่เปลี่ยนการวางแนวเมื่อฉันผู้ใช้เอียงโทรศัพท์
เควิน

4
วิธีการของ Apple ในการแก้ไขปัญหานี้เพื่อให้นักพัฒนาซอฟต์แวร์สามารถเปลี่ยน CSS ตามการเปลี่ยนแปลงการวางแนว แต่จะไม่ป้องกันการวางแนวใหม่ทั้งหมด ฉันพบคำถามที่คล้ายกันที่อื่น ๆ : ask.metafilter.com/99784/…
Scott Fox

2
ฉันเคยเห็นบางเว็บไซต์แสดงข้อความแนวนอนเท่านั้นที่บอกผู้ใช้ว่าไซต์นี้สามารถดูได้ในแนวตั้งเท่านั้น - เป็นอีกตัวเลือกหนึ่งสำหรับคุณที่จะต้องพิจารณา
Jayden Lawson

97

นี่เป็นวิธีแก้ปัญหาแฮ็กสวย แต่อย่างน้อยก็มีบางอย่าง (?) แนวคิดคือการใช้การแปลง CSS เพื่อหมุนเนื้อหาของหน้าเว็บของคุณไปเป็นโหมดเสมือนจริง นี่คือโค้ด JavaScript (แสดงเป็น jQuery) เพื่อให้คุณเริ่มต้น:

$(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);
});

รหัสคาดว่าเนื้อหาทั้งหมดของหน้าของคุณจะอยู่ใน div ภายในองค์ประกอบของร่างกาย มันหมุนที่ div 90 องศาในโหมดแนวนอน - กลับไปที่แนวตั้ง

ปล่อยให้เป็นแบบฝึกหัดให้กับผู้อ่าน: div จะหมุนรอบจุดศูนย์กลางดังนั้นจึงอาจต้องปรับตำแหน่งของตำแหน่งเว้นแต่จะเป็นรูปสี่เหลี่ยมจัตุรัสที่สมบูรณ์แบบ

นอกจากนี้ยังมีปัญหาการมองเห็นที่ไม่น่าดึงดูด เมื่อคุณเปลี่ยนการวางแนวซาฟารีจะหมุนอย่างช้าๆจากนั้น div ระดับบนสุดจะจับกันเป็น 90 เพื่อความสนุกสนานยิ่งขึ้นเพิ่ม

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

เพื่อ CSS ของคุณ เมื่ออุปกรณ์หมุนแล้ว Safari จะทำเช่นนั้นเนื้อหาของหน้าเว็บของคุณจะเป็นเช่นนั้น จับใจ!


3
Grumdrig คุณคือฮีโร่ของฉัน! นี่เป็นคำแนะนำเกี่ยวกับเว็บแอป iPhone ที่มีประโยชน์และใช้งานได้ดีที่สุดเท่าที่ฉันเคยเห็นในเว็บไซต์นี้ ขอบคุณมาก!
noober

ก่อนที่ฉันจะอ่านคำตอบนี้ฉันกำลังจะแนะนำความคิดเห็นคำตอบ "ยอมรับ" ที่ใครบางคนควรลองใช้และบอกฉันว่าทำงานได้หรือไม่ ฉันดีใจที่มีคนทำแล้วและมันก็ทำ!
Lane

เกิดอะไรขึ้นถ้า div เป็นสี่เหลี่ยม สูตรการตั้งค่าการแปลงต้นกำเนิดอย่างถูกต้องคืออะไร TA
superjos

นอกจากนี้คุณยังสามารถควบคุมได้โดยใช้ตัวเลือก "รองรับการวางแนวอินเตอร์เฟซ" บน xCode ภายใต้ข้อมูลการพัฒนา Iphone / iPod ทำงานได้ดี
Rodrigo Dias

1
เราหมุนร่างกายตัวเองไม่ได้เหรอ? พูดว่า $ ("body") css ("- webkit-transform",! portrait? "หมุน (-90deg)": "");
Krsna Chaitanya

39

คำตอบนี้ยังเป็นไปไม่ได้ แต่ฉันกำลังโพสต์ไว้สำหรับ "คนรุ่นอนาคต" หวังว่าสักวันเราจะสามารถทำได้ผ่านกฎ CSS @viewport:

@viewport {
    orientation: portrait;
}

นี่คือหน้า "ฉันสามารถใช้" ได้ (ตั้งแต่ 2019 เท่านั้น IE และ Edge):
https://caniuse.com/#feat=mdn-css_at-rules_viewport_orientation

ข้อมูลจำเพาะ (อยู่ระหว่างดำเนินการ):
https://drafts.csswg.org/css-device-adapt/#orientation-desc

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

จากตารางความเข้ากันได้ของเบราว์เซอร์ MDN และบทความต่อไปนี้ดูเหมือนว่ามีการสนับสนุนบางอย่างใน IE และ Opera บางรุ่น:
http://menacingcloud.com/?c=cssViewportOrMetaTag

JS API Spec นี้ยังมีความเกี่ยวข้อง:
https://w3c.github.io/screen-orientation/

ฉันสันนิษฐานว่าเพราะเป็นไปได้กับ@viewportกฎที่เสนอว่าจะเป็นไปได้โดยการตั้งค่าorientationในการตั้งค่าวิวพอร์ตในmetaแท็ก แต่ฉันยังไม่ประสบความสำเร็จกับสิ่งนี้

โปรดอัปเดตคำตอบนี้เมื่อสิ่งต่าง ๆ ดีขึ้น


ภายใน 10/2019 คุณลักษณะใหม่นี้ยังใช้งานไม่ได้ โปรดให้เราโพสต์ ขอบคุณ
RainCast

2
อันที่จริงมันใช้เวลานานมากฉันสงสัยว่ามันจะเคยเป็น ฉันได้เพิ่มลิงก์ไปยังหน้า "CanIUse"
xdhmoore

ขอบคุณ. คุณเป็นเจ้าของคุณลักษณะนี้หรือไม่ ฉันไม่เข้าใจว่าจะมีการเปิดใช้คุณลักษณะ css ใหม่อย่างไร ในการเดาของฉัน css org พูดคุยกับเจ้าของผลิตภัณฑ์เบราว์เซอร์รายใหญ่แต่ละรายและขอให้พวกเขาสนับสนุนหรือไม่ ใครเป็นผู้ควบคุมกระบวนการ ฉันอยากรู้มาก
RainCast

ฮาไม่ใช่แค่นักพัฒนาคนอื่น คุณกำลังมองหา W3C
xdhmoore

19

รหัสต่อไปนี้ถูกใช้ในเกม html5 ของเรา

$(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'); 
});

คุณจะหาตัวเลขเหล่านั้นสำหรับต้นกำเนิดการแปลงได้อย่างไร
superjos

3
คำเตือน!!! อุปกรณ์ทั้งหมดไม่รายงานค่าเดียวกันสำหรับการวางแนวดังนั้นจึงไม่สามารถเชื่อถือได้ในmatthewgifford.com/blog/2011/12/22/…
Rob

6

ฉันมากับ CSS นี้วิธีเดียวในการหมุนหน้าจอโดยใช้แบบสอบถามสื่อ แบบสอบถามจะขึ้นอยู่กับขนาดหน้าจอที่ผมพบว่าที่นี่ ดูเหมือนว่าจะดี 480px เนื่องจากอุปกรณ์ไม่กี่ชิ้นมีความกว้างมากกว่า 480px หรือสูงกว่า 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
    }
}

+1 โซลูชันที่ดี ฉันมีส่วนท้ายที่มีตำแหน่งคงที่ที่ด้านล่าง มีความคิดวิธีการแสดงหลังจากหมุน?
Cybrix

1
วิธีการเกี่ยวกับการใช้ (การวางแนว: แนวนอน) ในเคียวรีสื่อแทนที่จะเป็นค่าพิกเซลที่เฉพาะเจาะจง หรือจำเป็นต้องกำหนดค่าพิกเซลที่แน่นอน?
Justin Putney

ฉันใช้ค่าพิกเซลเพราะคุณต้องตั้งค่าที่แน่นอนใน html ซึ่งจะต้องตรงกับความสูงของหน้าจอ (เมื่ออยู่ในแนวนอน - ดังนั้นความกว้างของหน้าจอ) ดังนั้นการใช้งานorientation: landscapeจะไม่ทำงานได้ดีในตัวอย่างของฉัน @JustinPutney
Bill

1
จาก MDN: "หมายเหตุ: ค่านี้ไม่สอดคล้องกับการวางแนวอุปกรณ์จริงการเปิดแป้นพิมพ์นุ่ม ๆ บนอุปกรณ์ส่วนใหญ่ในแนวตั้งแนวตั้งจะทำให้วิวพอร์ตมีความกว้างมากกว่าความสูงจึงทำให้เบราว์เซอร์ใช้สไตล์แนวนอนแทนแนวตั้ง "
sheriffderek

2
ปฐมนิเทศ @ กฎสื่อ --- ใช่ คิดว่าพวกเขาเป็นวิธีที่จะไปจนกว่าฉันจะอ่านนี้: developer.mozilla.org/en-US/docs/Web/Guide/CSS//
sheriffderek



2

อาจเป็นในอนาคตใหม่ที่จะมีการออกนอกกรอบ ...

สำหรับเดือนพฤษภาคม 2558

มีฟังก์ชันการทดลองที่ทำเช่นนั้น

แต่ใช้ได้กับ Firefox 18+, IE11 + และ Chrome 38+ เท่านั้น

อย่างไรก็ตามมันยังไม่สามารถใช้งานบน Opera หรือ Safari ได้

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

นี่คือรหัสปัจจุบันสำหรับเบราว์เซอร์ที่ใช้งานร่วมกันได้:

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

lockOrientation("landscape-primary");

ฉันใช้มันในรหัสจาวาสคริปต์ในเว็บไซต์เวิร์ดเพรสของฉันเป็น: screen.lockOrientation ("landscape"); และมันไม่ทำงาน ฉันได้รับ: jQuery (... ). lockOrientation ไม่ใช่ฟังก์ชั่น ฉันจำเป็นต้องใช้ปลั๊กอินหรือกรอบงานใด ๆ หรือไม่?
Alex Stanese

1

ในขณะที่คุณไม่สามารถป้องกันการเปลี่ยนแปลงการวางแนวจากการมีผลคุณสามารถเลียนแบบการเปลี่ยนแปลงตามที่ระบุไว้ในคำตอบอื่น ๆ

ขั้นแรกตรวจหาการวางแนวของอุปกรณ์หรือการปรับตำแหน่งใหม่และโดยใช้ JavaScript ให้เพิ่มชื่อคลาสลงในองค์ประกอบห่อของคุณ (ในตัวอย่างนี้ฉันใช้แท็ก body)

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();

จากนั้นหากอุปกรณ์เป็นแนวนอนให้ใช้ CSS เพื่อตั้งค่าความกว้างของร่างกายเป็นความสูงวิวพอร์ตและความสูงของร่างกายเป็นความกว้างวิวพอร์ต และลองตั้งจุดกำเนิดการแปลงขณะที่เราอยู่ที่นั้น

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

ตอนนี้ปรับองค์ประกอบของร่างกายและเลื่อน (แปล) ลงในตำแหน่ง

body.rotation-90 {
  transform: rotate(90deg) translateY(-100%);
}
body.rotation90 {
  transform: rotate(-90deg) translateX(-100%);
}

0
// CSS hack to prevent layout breaking in landscape
// e.g. screens larger than 320px  
html {
  width: 320px;
  overflow-x: hidden;
}

อย่างน้อยนี่หรือโซลูชัน CSS ที่คล้ายกันจะรักษาเค้าโครงของคุณอย่างน้อยถ้านั่นคือสิ่งที่คุณเป็น

โซลูชันรูทคือการบัญชีสำหรับความสามารถของอุปกรณ์แทนที่จะพยายาม จำกัด ไว้ หากอุปกรณ์ไม่อนุญาตให้คุณมีข้อ จำกัด ที่เหมาะสมกว่าการแฮ็กแบบง่าย ๆ เป็นทางออกที่ดีที่สุดของคุณเนื่องจากการออกแบบนั้นไม่สมบูรณ์ ง่ายกว่าดีกว่า


0

ในกาแฟถ้าใครต้องการมัน

    $(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)"

0

แรงบันดาลใจจากคำตอบของ @ Grumdrig และเนื่องจากคำแนะนำที่ใช้บางอย่างจะไม่ทำงานฉันจึงแนะนำสคริปต์ต่อไปนี้หากต้องการโดยบุคคลอื่น:

    $(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);
    });

0

ฉันมีปัญหาที่คล้ายกัน แต่เพื่อให้ภูมิประเทศ ... ฉันเชื่อว่ารหัสด้านล่างควรทำเคล็ดลับ:

//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>


-3

คลิกที่นี่สำหรับตัวอย่างการสอนและตัวอย่างการใช้งานจากเว็บไซต์ของฉัน

คุณไม่จำเป็นต้องใช้แฮ็กเพียงเพื่อดู jQuery Mobile Screen Orientation และคุณไม่ควรใช้ PhoneGap อีกต่อไปเว้นแต่คุณจะใช้ PhoneGap จริงๆ

เพื่อให้งานนี้ในปี 2558 เราต้องการ:

  • Cordova (รุ่นใด ๆ ก็ตาม แต่สิ่งที่สูงกว่า 4.0 จะดีกว่า)
  • PhoneGap (คุณสามารถใช้ PhoneGap ได้, ปลั๊กอินเข้ากันได้)

และหนึ่งในปลั๊กอินเหล่านี้ขึ้นอยู่กับรุ่น Cordova ของคุณ:

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

ปลั๊กอินคอร์โดวาเพิ่ม net.yoik.cordova.plugins.screenorientation

  • ปลั๊กอิน Cordova เพิ่ม Cordova-plugin-screen-Orient (Cordova> = 4)

ปลั๊กอิน Cordova เพิ่ม Cordova-plugin-screen-Orient

และเพื่อล็อคการวางแนวหน้าจอเพียงใช้ฟังก์ชั่นนี้:

screen.lockOrientation('landscape');

วิธีปลดล็อก:

screen.unlockOrientation();

ทิศทางที่เป็นไปได้:

  • portrait-primaryปฐมนิเทศอยู่ในโหมดแนวตั้งหลัก

  • Portrait-Secondaryการวางแนวอยู่ในโหมด Portrait รอง

  • แนวนอนหลักปฐมนิเทศอยู่ในโหมดแนวนอนหลัก

  • landscape-Secondaryการวางแนวอยู่ในโหมดแนวนอนรอง

  • portraitการวางแนวเป็นแนวตั้ง - หลักหรือแนวตั้ง - รอง (เซ็นเซอร์)

  • แนวนอนการวางแนวเป็นแนวนอนหลักหรือแนวนอนรอง (เซ็นเซอร์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.