Phát hiện xoay vòng điện thoại Android trong trình duyệt bằng JavaScript


187

Tôi biết rằng trong Safari trên iPhone, bạn có thể phát hiện hướng của màn hình và thay đổi hướng bằng cách lắng nghe onorientationchangesự kiện và truy vấn window.orientationgóc.

Điều này có thể có trong trình duyệt trên điện thoại Android?

Để rõ ràng, tôi đang hỏi liệu xoay vòng của một thiết bị Android có thể được phát hiện bằng JavaScript chạy trên một trang web tiêu chuẩn hay không. Có thể có trên iPhone và tôi tự hỏi liệu nó có thể được thực hiện cho điện thoại Android hay không.

Câu trả lời:


214

Để phát hiện thay đổi hướng trên trình duyệt Android, hãy đính kèm một trình lắng nghe vào orientationchangehoặc resizesự kiện trên window:

// Detect whether device supports orientationchange event, otherwise fall back to
// the resize event.
var supportsOrientationChange = "onorientationchange" in window,
    orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";

window.addEventListener(orientationEvent, function() {
    alert('HOLY ROTATING SCREENS BATMAN:' + window.orientation + " " + screen.width);
}, false);

Kiểm tra window.orientationtài sản để tìm ra cách thiết bị được định hướng. Với điện thoại Android, screen.widthhoặc screen.heightcũng có thể cập nhật khi thiết bị được xoay. (đây không phải là trường hợp của iPhone).


cái này có thực sự hiệu quả không? tôi đã thử jquery $ (window) .bind ("directionchange", fn); Nhưng nó không hoạt động, tôi có phải sử dụng mẫu ở trên không? tôi đã thử "onorientationchange" trong cửa sổ, nó chạy lại sai
Ayyash

Nó hoạt động tốt. Ayyash - toàn bộ vấn đề ở đây là khi "trao đổi định hướng" không được hỗ trợ, nó sẽ quay trở lại "thay đổi kích thước"
Dror

9
Trên Droid này là hoàn toàn điên rồ. Nó cảnh báo màn hình. Băng thông 320 khi điện thoại được xoay ở chế độ ngang và phát hiện màn hình. Băng thông 569 khi điện thoại được xoay ở chế độ dọc! Làm thế nào mà??
IgorGanapolsky

1
Chỉ cần làm rõ: Những người đang tìm kiếm một giải pháp cũng hoạt động trên iOS nên xem câu trả lời của hai kẻ ngốc hoặc câu trả lời của tôi.
mkuity0

3
Không cần sử dụng hack hai bit cho iOS. Chỉ cần sử dụng screen. Thong và screen.height trên Android và trên iOS, sử dụng window.innerWidth và window.innerHeight.
Justin

224

Hành vi thực tế trên các thiết bị khác nhau là không nhất quán . Các sự kiện thay đổi kích thước và định hướng có thể kích hoạt theo một chuỗi khác nhau với tần suất khác nhau. Ngoài ra, một số giá trị (ví dụ: screen. Thong và window.orientation) không luôn thay đổi khi bạn mong đợi. Tránh màn hình. Băng thông - nó không thay đổi khi xoay trong iOS.

Cách tiếp cận đáng tin cậy là lắng nghe cả hai sự kiện thay đổi kích thước và định hướng Thay đổi (với một số bỏ phiếu là một biện pháp an toàn) và cuối cùng bạn sẽ nhận được giá trị hợp lệ cho hướng. Trong thử nghiệm của tôi, các thiết bị Android đôi khi không thể kích hoạt các sự kiện khi xoay 180 độ đầy đủ, do đó tôi cũng đã bao gồm một giá trị xác định để thăm dò hướng.

var previousOrientation = window.orientation;
var checkOrientation = function(){
    if(window.orientation !== previousOrientation){
        previousOrientation = window.orientation;
        // orientation changed, do your magic here
    }
};

window.addEventListener("resize", checkOrientation, false);
window.addEventListener("orientationchange", checkOrientation, false);

// (optional) Android doesn't always fire orientationChange on 180 degree turns
setInterval(checkOrientation, 2000);

Dưới đây là kết quả từ bốn thiết bị mà tôi đã thử nghiệm (xin lỗi cho bảng ASCII, nhưng có vẻ như là cách dễ nhất để trình bày kết quả). Bên cạnh sự thống nhất giữa các thiết bị iOS, có rất nhiều sự đa dạng trên các thiết bị. LƯU Ý: Các sự kiện được liệt kê theo thứ tự mà chúng bắn.

| ================================================= ============================= |
| Thiết bị | Sự kiện bắn | định hướng | trongWidth | màn hình. Băng thông |
| ================================================= ============================= |
| iPad 2 | thay đổi kích thước | 0 | 1024 | 768 |
| (đến phong cảnh) | định hướng | 90 | 1024 | 768 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPad 2 | thay đổi kích thước | 90 | 768 | 768 |
| (để chân dung) | định hướng | 0 | 768 | 768 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPhone 4 | thay đổi kích thước | 0 | 480 | 320 |
| (đến phong cảnh) | định hướng | 90 | 480 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPhone 4 | thay đổi kích thước | 90 | 320 | 320 |
| (để chân dung) | định hướng | 0 | 320 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Điện thoại Droid | định hướng | 90 | 320 | 320 |
| (đến phong cảnh) | thay đổi kích thước | 90 | 569 | 569 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Điện thoại Droid | định hướng | 0 | 569 | 569 |
| (để chân dung) | thay đổi kích thước | 0 | 320 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Thiên hà Samsung | định hướng | 0 | 400 | 400 |
| Máy tính bảng | định hướng | 90 | 400 | 400 |
| (đến phong cảnh) | định hướng | 90 | 400 | 400 |
| | thay đổi kích thước | 90 | 683 | 683 |
| | định hướng | 90 | 683 | 683 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Thiên hà Samsung | định hướng | 90 | 683 | 683 |
| Máy tính bảng | định hướng | 0 | 683 | 683 |
| (để chân dung) | định hướng | 0 | 683 | 683 |
| | thay đổi kích thước | 0 | 400 | 400 |
| | định hướng | 0 | 400 | 400 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |

Trong trình giả lập iOS5, nếu bạn làm mới theo chiều ngang thì xoay, mã này không kích hoạt.
làm việc

1
Câu trả lời chính xác. previousOrientationnên được khởi tạo với hướng hiện tại: var previousOrientation = window.orientation;Nếu bạn muốn bỏ qua các góc quay 180 độ, nghĩa là, bạn không cần phân biệt giữa phong cảnh trái hoặc phải và các biến thể lộn ngược hoặc không, hãy thêm vào sau như dòng đầu tiên checkOrientation(): if (0 === (previousOrientation + window.orientation) % 180) return;Tuy nhiên, không có setTimeoutthủ thuật bổ sung , bạn sẽ chỉ được hưởng lợi từ điều này trên iOS, trong đó xoay 180 độ nhanh chóng chỉ tạo ra một sự kiện duy nhất orientationchange .
mkuity0

Cảm ơn @mkuity, tôi đã điều chỉnh mã để khởi tạo trước đó.
kẻ ngốc hai bit

Chúc mừng cho những thông tin tuyệt vời. Điều này đã làm tôi suy nghĩ vì windows phone 8.1 không có sự kiện thay đổi kích thước hoặc định hướng khi bạn sử dụng cordova. Sử dụng setInterval cũng như failafe.
Sự hoàn hảo

@ mkuity0 Đến ngày hôm nay window.orientation sẽ luôn không được xác định trên windows phone 8.1.
Sự hoàn hảo

39

Câu trả lời tuyệt vời của hai-bit-trick cung cấp tất cả nền tảng, nhưng hãy để tôi thử tóm tắt ngắn gọn, thực tế về cách xử lý các thay đổi định hướng trên iOS và Android :

  • Nếu bạn chỉ quan tâm đến kích thước cửa sổ (kịch bản điển hình) - chứ không quan tâm đến hướng cụ thể:
    • Chỉ xử lý resizesự kiện.
    • Trong xử lý của bạn, hành động window.innerWidthwindow.InnerHeightchỉ.
    • KHÔNG sử dụng window.orientation- nó sẽ không hiện hành trên iOS.
  • Nếu bạn quan tâm đến định hướng cụ thể :
    • Xử lý chỉ các resizesự kiện trên Android, và chỉ những orientationchangesự kiện trên iOS.
    • Trong xử lý của bạn, hành động trên window.orientation(và window.innerWidthwindow.InnerHeight)

Những cách tiếp cận này mang lại lợi ích nhỏ so với việc ghi nhớ định hướng trước đó và so sánh:

  • phương pháp chỉ kích thước cũng hoạt động trong khi phát triển trên các trình duyệt máy tính để bàn có thể mô phỏng các thiết bị di động, ví dụ: Chrome 23. ( window.orientationkhông khả dụng trên các trình duyệt máy tính để bàn).
  • không cần biến toàn cục / ẩn danh tập tin cấp hàm-hàm-hàm-trình bao bọc.

Vấn đề là khi thay đổi kích thước hoặc sự kiện định hướng kích hoạt window.innerWidth báo cáo sai và các thiết bị Droid
albanx

@albanx vẫn còn là một vấn đề trong chrome trên ios: / safari vẫn ổn tho
oldboy

12

Bạn luôn có thể nghe sự kiện thay đổi kích thước cửa sổ. Nếu, trong sự kiện đó, cửa sổ chuyển từ cao hơn rộng sang rộng hơn cao (hoặc ngược lại), bạn có thể chắc chắn rằng hướng điện thoại vừa được thay đổi.


Đó là một ý tưởng hay, tôi sẽ thử nó (và nhờ bạn tôi dùng điện thoại Android để kiểm tra!)
philnash

Tôi mới nhận ra rằng phương pháp này không mang lại cho tôi định hướng của điện thoại. Tôi sẽ biết liệu đó là chân dung hay phong cảnh, nhưng không phải nếu nó lộn ngược hoặc đã được quay sang trái hoặc sang phải. Còn ý tưởng nào nữa không?
philnash

Tôi không chắc làm thế nào nó có thể có thể quan trọng ... Tại sao bạn cần biết nếu điện thoại bị lộn ngược? Trình duyệt điện thoại có một đầu trang và trang web sẽ được định hướng đến đầu trình duyệt. Bất kỳ người dùng nào có hai tế bào não cọ xát với nhau, những người nhìn vào một trang web lộn ngược sẽ chỉ quay điện thoại của họ nếu họ muốn nhìn thấy nó ngay bên phải
Joel Mueller

1
Đó là một chút khắc nghiệt. Tôi muốn biết rằng tôi có thể hiển thị nội dung khác nhau dựa trên hướng của màn hình, đây có thể là tối đa 4 trang khác nhau, yêu cầu trình duyệt phải biết liệu nó có bị xoay 0, 90, 180 và 270 độ hay không. Đây là tất cả có thể, trong JavaScript, trên iPhone và là lý do tại sao tôi hỏi.
philnash

Tôi vẫn gặp khó khăn khi hình dung những gì một trang web có thể làm khác đi một cách hữu ích khi thiết bị được hiển thị được xoay 270 độ, nhưng nếu bạn nói rằng bạn có một trường hợp sử dụng hợp lệ, tôi sẽ không ngụy biện. Trong trường hợp đó: tôi xin lỗi, nhưng tôi không biết trình duyệt Android có cung cấp mức độ chi tiết này không.
Joel Mueller

3

Có thể có trong HTML5.
Bạn có thể đọc thêm (và thử bản demo trực tiếp) tại đây: http://slides.html5rocks.com/#slide-orientation .

window.addEventListener('deviceorientation', function(event) {
    var a = event.alpha;
    var b = event.beta;
    var g = event.gamma;
}, false);

Nó cũng hỗ trợ các trình duyệt để bàn nhưng nó sẽ luôn trả về cùng một giá trị.


4
Sự kiện này thực sự nhiều hơn để truy cập vào các cảm biến chuyển động, mặc dù tôi cho rằng nó cũng có thể được sử dụng để phát hiện sự thay đổi hướng.
René

Trên Android Galaxy S2 của tôi, nó không được hỗ trợ trên trình duyệt chứng khoán cũng như Trình duyệt cá heo. Nhưng hoạt động tốt với firefox di động.
Eduardo

3

Tôi đã từng gặp vấn đề tương tự. Tôi đang sử dụng Phonegap và Jquery mobile, cho các thiết bị Adroid. Để thay đổi kích thước đúng, tôi phải đặt thời gian chờ:

$(window).bind('orientationchange',function(e) {
  fixOrientation();
});

$(window).bind('resize',function(e) {
  fixOrientation();
});

function fixOrientation() {

    setTimeout(function() {

        var windowWidth = window.innerWidth;

        $('div[data-role="page"]').width(windowWidth);
        $('div[data-role="header"]').width(windowWidth);
        $('div[data-role="content"]').width(windowWidth-30);
        $('div[data-role="footer"]').width(windowWidth);

    },500);
}

2

Đây là giải pháp:

var isMobile = {
    Android: function() {
        return /Android/i.test(navigator.userAgent);
    },
    iOS: function() {
        return /iPhone|iPad|iPod/i.test(navigator.userAgent);
    }
};
if(isMobile.Android())
    {
        var previousWidth=$(window).width();
        $(window).on({
        resize: function(e) {
        var YourFunction=(function(){

            var screenWidth=$(window).width();
            if(previousWidth!=screenWidth)
            {
                previousWidth=screenWidth;
                alert("oreientation changed");
            }

        })();

        }
    });

    }
    else//mainly for ios
    {
        $(window).on({
            orientationchange: function(e) {
               alert("orientation changed");
            }   
        });
    }

Đây là giải pháp phù hợp nhất với tôi, tôi biết nó không chính xác 100% nhưng bạn có thể phát hiện ngang và dọc bằng cách sử dụng: var screenWidth = $ (window). Thong (); var screenHeight = $ (cửa sổ) .height (); if (screenWidth> screenHeight) {doS Something (); }
math0ne

Đây là giải pháp cho tôi trên máy tính bảng Android nhảm nhí. window.onresize, đính kèm và addeventlistener không thành công trên nhiều sự kiện (thay đổi kích thước, onresize, định hướng trao đổi, thiết bị hóa). Chỉ Jquery $ (cửa sổ) .on () làm việc.
Lego

1

Một hình ảnh xác thực khác - một số máy tính bảng Android (Motorola Xoom tôi tin và một chiếc Elonex cấp thấp tôi đang thực hiện một số thử nghiệm, có lẽ cũng vậy) có các máy đo gia tốc của chúng được thiết lập sao cho window.orientation == 0 ở chế độ LANDSCAPE, không phải chân dung !


1

bạn có thể thử giải pháp, tương thích với tất cả các trình duyệt.

Sau đây là orientationchangepic tương thích: khả năng tương thích do đó, tôi là tác giả của một orientaionchangepolyfill, nó dựa trên thuộc tính @media để sửa thư viện tiện ích định hướng trao đổi định hướng

window.addEventListener('orientationchange', function(){
 if(window.neworientation.current === 'portrait|landscape'){
    // do something……
 } else {
    // do something……
 }
}, false);

0

Đáng chú ý là trên Epic 4G Touch của tôi, tôi đã phải thiết lập chế độ xem web để sử dụng WebChromClient trước khi bất kỳ cuộc gọi android javascript nào hoạt động.

webView.setWebChromeClient(new WebChromeClient());

0

Cách trình duyệt chéo

$(window).on('resize orientationchange webkitfullscreenchange mozfullscreenchange fullscreenchange',  function(){
//code here
});

-1

Một đóng góp nhỏ cho câu trả lời của hai kẻ ngốc:

Như được mô tả trên bảng trên sự kiện "định hướng" của điện thoại droid được kích hoạt sớm hơn sự kiện "thay đổi kích thước", do đó chặn cuộc gọi thay đổi kích thước tiếp theo (vì câu lệnh if). Thuộc tính chiều rộng vẫn chưa được đặt.

Một cách giải quyết mặc dù có thể không hoàn hảo có thể là không kích hoạt sự kiện "trao đổi định hướng". Điều đó có thể được lưu trữ bằng cách gói ràng buộc sự kiện "định hướng" trong câu lệnh "if":

if (!navigator.userAgent.match(/android/i))
{
    window.addEventListener("orientationchange", checkOrientation, false);
}

Hy vọng nó giúp

(các thử nghiệm đã được thực hiện trên Nexus S)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.