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


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 onorientationchange sự kiện và truy vấn window.orientation cho góc.

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

Để rõ ràng, tôi hỏi liệu việc xoay vòng thiết bị Android có thể được phát hiện bởi JavaScript chạy trên trang web chuẩn. Có thể 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.


177
2017-10-30 10:43


gốc




Các câu trả lời:


Để phát hiện thay đổi định hướng trên trình duyệt Android, hãy đính kèm trình nghe vào orientationchange hoặc là resize sự 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.orientation tài sản để tìm ra cách mà thiết bị được định hướng. Với điện thoại Android, screen.width hoặc là screen.height cũng cập nhật khi thiết bị được xoay. (đây không phải là trường hợp với iPhone).


204
2018-02-21 23:37



Điều này dường như không hoạt động trên Nexus One - Jeremy
đã cập nhật mã cho nexus one - jb.
Trên Droid, điều này hoàn toàn điên rồ. Nó cảnh báo screen.width của 320 khi điện thoại được xoay ở chế độ nằm ngang, và nó phát hiện screen.width 569 khi điện thoại được xoay ở chế độ dọc! Làm thế nào mà?? - Igor Ganapolsky
Chỉ cần làm rõ: Những người đang tìm kiếm giải pháp cũng hoạt động trên iOS nên nhìn vào câu trả lời của hai người hoặc câu trả lời của tôi. - mklement0
Không cần sử dụng hack hai bit cho iOS. Chỉ cần sử dụng screen.width và screen.height trên Android và trên iOS, sử dụng window.innerWidth và window.innerHeight. - Justin


Thực tế hành vi trên các thiết bị khác nhau không nhất quán. Các sự kiện thay đổi kích thước và orientationChange có thể kích hoạt theo trình tự khác với tần số thay đổi. Ngoài ra, một số giá trị (ví dụ: screen.width và window.orientation) không phải lúc nào cũng thay đổi khi bạn mong đợi. Tránh screen.width - nó không thay đổi khi quay 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 (với một số thăm dò ý kiến ​​như là một bắt an toàn), và cuối cùng bạn sẽ nhận được một giá trị hợp lệ cho định hướng. Trong thử nghiệm của tôi, thiết bị Android đôi khi không cháy các sự kiện khi quay 180 độ đầy đủ, vì vậy tôi cũng đã bao gồm một setInterval để thăm dò ý kiến ​​định 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);

Đâ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 nó có vẻ giống như cách dễ nhất để trình bày kết quả). Ngoài sự nhất quán 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 đã kích hoạt.

| ================================================= ============================= |
| Thiết bị | Sự kiện được kích hoạt | định hướng | innerWidth | screen.width |
| ================================================= ============================= |
| iPad 2 | thay đổi kích thước | 0 | 1024 | 768 |
| (đến phong cảnh) | orientationchange | 90 | 1024 | 768 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPad 2 | thay đổi kích thước | 90 | 768 | 768 |
| (để chân dung) | orientationchange | 0 | 768 | 768 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPhone 4 | thay đổi kích thước | 0 | 480 | 320 |
| (đến phong cảnh) | orientationchange | 90 | 480 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPhone 4 | thay đổi kích thước | 90 | 320 | 320 |
| (để chân dung) | orientationchange | 0 | 320 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Điện thoại Droid | orientationchange | 90 | 320 | 320 |
| (đến phong cảnh) | thay đổi kích thước | 90 | 569 | 569 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Điện thoại Droid | orientationchange | 0 | 569 | 569 |
| (để chân dung) | thay đổi kích thước | 0 | 320 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Samsung Galaxy | orientationchange | 0 | 400 | 400 |
| Máy tính bảng | orientationchange | 90 | 400 | 400 |
| (đến phong cảnh) | orientationchange | 90 | 400 | 400 |
| | thay đổi kích thước | 90 | 683 | 683 |
| | orientationchange | 90 | 683 | 683 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Samsung Galaxy | orientationchange | 90 | 683 | 683 |
| Máy tính bảng | orientationchange | 0 | 683 | 683 |
| (để chân dung) | orientationchange | 0 | 683 | 683 |
| | thay đổi kích thước | 0 | 400 | 400 |
| | orientationchange | 0 | 400 | 400 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |

216
2017-07-06 21:54



Cảm ơn bạn đã trả lời rất kỹ lưỡng! - RichieHindle
Điều này thật tuyệt. - ThinkingStiff
Trong trình mô phỏng iOS5, nếu bạn làm mới ở chế độ ngang thì xoay, mã này không kích hoạt. - worked
Thật là một mớ hỗn độn, cảm ơn câu trả lời chi tiết! - travis
Câu trả lời chính xác. previousOrientation nên được khởi tạo với định hướng sau đó: var previousOrientation = window.orientation;Nếu bạn muốn bỏ qua phép xoay 180 độ, tức là bạn không cần phải phân biệt giữa cảnh quan bên trái hoặc bên phải và các biến thể lộn ngược hoặc không, hãy thêm dòng sau làm dòng đầu tiên checkOrientation(): if (0 === (previousOrientation + window.orientation) % 180) return; Tuy nhiên, không có thêm setTimeout lừa đảo, bạn sẽ chỉ được hưởng lợi từ điều này trên iOS, nơi xoay vòng 180 độ nhanh chóng chỉ tạo ra Độc thân  orientationchange biến cố. - mklement0


câu trả lời xuất sắc của hai-bit-fool cung cấp tất cả nền, nhưng hãy để tôi thử tóm tắt ngắn gọn, thực dụng 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 kích thước cửa sổ (kịch bản điển hình) - và không phải về định hướng cụ thể:
    • Xử lý resize chỉ sự kiện.
    • Trong trình xử lý của bạn, hãy hành động window.innerWidth và window.InnerHeight chỉ có.
    • Không được dùng window.orientation - nó sẽ không có trên iOS.
  • Nếu bạn quan tâm đến định hướng cụ thể:
    • Xử lý chỉ có các resize sự kiện trên Android và chỉ có các orientationchange sự kiện trên iOS.
    • Trong trình xử lý của bạn, hãy hành động window.orientation (và window.innerWidth và window.InnerHeight)

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

  • phương pháp chỉ tham số cũng hoạt động trong khi phát triển trên các trình duyệt trên máy tính để bàn có thể mô phỏng thiết bị di động bằng cách khác, ví dụ: Chrome 23. (window.orientation không khả dụng trên trình duyệt trên máy tính để bàn).
  • không cần biến global / anonymous-file-level-function-wrapper-level.

38
2017-12-10 16:34



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


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


12
2017-10-30 17:21



Đó là một ý tưởng hay, tôi sẽ thử (và nhờ bạn tôi cùng điện thoại Android kiểm tra!) - philnash
Tôi vừa mới nhận ra rằng phương pháp này không cho tôi định hướng của điện thoại. Tôi sẽ biết liệu nó là chân dung hay phong cảnh, nhưng không phải là nó bị đảo lộn hoặc bị chuyển 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 nó có thể có vấn đề như thế nào ... Tại sao bạn cần biết điện thoại có bị lộn ngược không? Trình duyệt của điện thoại có đầu trang và trang web sẽ được định hướng ở đầu của trình duyệt. Bất kỳ người dùng nào có hai tế bào não để chà xát cùng nhau, những người đang xem 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ó ở bên phải - Joel Mueller
Đó là một chút khắc nghiệt. Tôi muốn biết để 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, điều này có thể lên đến 4 trang khác nhau, yêu cầu trình duyệt biết liệu nó có được xoay theo 0, 90, 180 và 270 độ hay không. Điều này là tất cả có thể, trong JavaScript, trên iPhone và là lý do tại sao tôi yêu cầu. - philnash
Tôi vẫn đang gặp khó khăn khi hình dung một trang web có thể làm gì 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ó trường hợp sử dụng hợp lệ, tôi sẽ không giải thích. Trong trường hợp đó: Tôi xin lỗi, nhưng tôi không biết liệu trình duyệt Android có cung cấp mức chi tiết này không. - Joel Mueller


Có thể trong HTML5.
Bạn có thể đọc thêm (và thử 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ợ trình duyệt deskop nhưng nó sẽ luôn luôn trả về cùng một giá trị.


3
2017-07-21 22:52



Sự kiện này thực sự là 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 định 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 Dolphin. Nhưng hoạt động tốt với firefox di động. - Eduardo


Tôi đã từng gặp vấn đề tương tự. Tôi đang sử dụng điện thoại di động của Phonegap và Jquery cho thiết bị Adroid. Để thay đổi kích thước đúng cách, 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
2018-01-22 11:02





Đâ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");
            }   
        });
    }

2
2018-02-11 16:18



Đây là giải pháp làm việc tốt nhất cho 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 vs dọc bằng cách sử dụng này: var screenWidth = $ (window) .width (); var screenHeight = $ (cửa sổ) .height (); if (screenWidth> screenHeight) {doSomething (); } - math0ne
Đây là một giải pháp cho tôi trên một máy tính bảng Android khốc liệt. window.onresize, attachevent và addeventlistener thất bại trên nhiều sự kiện (thay đổi kích thước, onresize, orientationchange, định vị). Chỉ Jquery $ (cửa sổ) .on () làm việc. - Lego


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

webView.setWebChromeClient(new WebChromeClient());

0
2018-02-08 18:34





Một lưu ý 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 mà tôi đang thực hiện một số thử nghiệm, có lẽ những người khác nữa) đã cài đặt gia tốc để window.orientation == 0 ở chế độ LANDSCAPE, chứ không phải dọc !


0
2018-03-29 10:35