iOS 8 đã loại bỏ các thuộc tính viewport tối thiểu, có các giải pháp màn hình mềm toàn màn hình khác của Cameron không?


191

(Đây là một câu hỏi gồm nhiều phần, tôi sẽ cố gắng hết sức để tóm tắt kịch bản.)

Chúng tôi hiện đang xây dựng một ứng dụng web đáp ứng (trình đọc tin tức) cho phép người dùng vuốt giữa các nội dung được gắn thẻ, cũng như cuộn theo chiều dọc bên trong mỗi nội dung được gắn thẻ.

Một cách tiếp cận phổ biến cho vấn đề là có một trình bao bọc divlấp đầy khung nhìn trình duyệt, được đặt overflowthành hiddenhoặc autosau đó cuộn theo chiều ngang và / hoặc theo chiều dọc bên trong nó.

Cách tiếp cận này rất hay nhưng có một nhược điểm chính: vì chiều cao của tài liệu hoàn toàn giống với chế độ xem của trình duyệt, trình duyệt di động sẽ không ẩn thanh địa chỉ / menu điều hướng .

rất nhiều hack và thuộc tính khung nhìn cho phép chúng tôi có được nhiều bất động sản màn hình hơn, nhưng không có tính năng nào hiệu quả như minimal-ui(được giới thiệu trong iOS 7.1).

Tin tức đến ngày hôm qua rằng iOS 8 beta4 đã bị xóa minimal-uikhỏi Mobile Safari (xem phần Webkit trong Ghi chú phát hành iOS 8 ), khiến chúng tôi tự hỏi:

Q1. Vẫn có thể ẩn thanh địa chỉ trên Mobile Safari?

Theo như chúng tôi biết, iOS 7 không còn phản ứng với vụ window.scrollTohack nữa, điều này cho thấy chúng tôi phải sống với không gian màn hình nhỏ hơn, trừ khi chúng tôi áp dụng bố cục dọc hoặc sử dụng mobile-web-app-capable.

Quý 2 Vẫn có thể có một trải nghiệm toàn màn hình mềm tương tự?

Bởi toàn màn hình mềm tôi thực sự có nghĩa là không sử dụng mobile-web-app-capablethẻ meta.

Ứng dụng web của chúng tôi được xây dựng để có thể truy cập, bất kỳ trang nào cũng có thể được đánh dấu hoặc chia sẻ bằng menu trình duyệt gốc. Bằng cách thêm mobile-web-app-capablechúng tôi ngăn người dùng gọi menu như vậy (khi nó được lưu vào màn hình chính), điều này gây nhầm lẫn và phản đối người dùng.

minimal-uitừng là trung gian, ẩn menu theo mặc định nhưng giữ cho nó có thể truy cập bằng một cú chạm - mặc dù Apple có thể đã xóa nó do những lo ngại về khả năng truy cập khác (chẳng hạn như người dùng không biết nhấn vào đâu để kích hoạt menu).

H3 Là một trải nghiệm toàn màn hình có giá trị rắc rối?

Có vẻ như API toàn màn hình sẽ không sớm xuất hiện trên iOS, nhưng ngay cả khi đó, tôi không thấy menu sẽ được giữ như thế nào (tương tự với Chrome trên Android).

Trong trường hợp này, có lẽ chúng ta chỉ nên rời khỏi safari trên thiết bị di động và tính đến chiều cao của khung nhìn (đối với iPhone 5+, đó là 460 = 568 - 108, trong đó 108 bao gồm thanh OS, thanh địa chỉ và menu điều hướng; cho iPhone 4 hoặc cũ hơn, đó là 372).

Rất thích nghe một số lựa chọn thay thế (bên cạnh việc xây dựng một ứng dụng gốc).


xem stackoverflow.com/questions/18793072/ để biết thêm chi tiết về lý do tại sao tối thiểu có thể rất quan trọng đối với một số ứng dụng.
bitinn

1
Tôi gặp vấn đề tương tự trên iOS 7, khi chúng tôi đang tìm cách xây dựng một ứng dụng web với các sự kiện vuốt / cuộn, nhưng đã thử nghiệm các sự kiện onScroll trên iOS8 Beta 4 và .. chúng hoạt động. ios8-scroll-events.heroku.com Không chắc điều đó có giúp ích gì không nhưng .. bạn có điều đó sẽ giúp bạn.
Devin McInni

Ran vào cùng rắc rối. Hiện tại chỉ có javascript "fix", vì hàm calc () bên dưới là câu trả lời duy nhất. Hãy giữ chủ đề này được cập nhật, nếu bạn biết một quyết định tốt hơn. Trân trọng.
A1exandr

Câu trả lời:


86

Thuộc tính khung nhìn tối thiểu không còn được hỗ trợ trong iOS 8. Tuy nhiên, bản thân ui tối thiểu không biến mất. Người dùng có thể nhập ui tối thiểu bằng cử chỉ "chạm-kéo xuống".

Có một số điều kiện tiên quyết và trở ngại để quản lý trạng thái xem, ví dụ để tối thiểu hoạt động, phải có đủ nội dung để cho phép người dùng cuộn; để duy trì tối thiểu, cuộn cửa sổ phải được bù khi tải trang và sau khi thay đổi hướng. Tuy nhiên, không có cách tính kích thước của ui tối thiểu bằng cách sử dụng screenbiến và do đó, không có cách nào để biết khi nào người dùng ở mức tối thiểu trước.

Những quan sát này là kết quả của nghiên cứu như là một phần của việc phát triển Brim - trình quản lý xem cho iOS 8 . Việc thực hiện kết thúc hoạt động theo cách sau:

Khi trang được tải, Brim sẽ tạo ra một yếu tố máy chạy bộ. Yếu tố máy chạy bộ được sử dụng để cung cấp cho người dùng không gian để cuộn. Sự hiện diện của yếu tố máy chạy bộ đảm bảo rằng người dùng có thể vào chế độ xem tối thiểu và nó sẽ tiếp tục tồn tại nếu người dùng tải lại trang hoặc thay đổi hướng thiết bị. Nó là vô hình cho người dùng toàn bộ thời gian. Phần tử này có ID brim-treadmill.

Khi tải trang hoặc sau khi thay đổi hướng, Brim đang sử dụng Scream để phát hiện xem trang có ở chế độ xem tối thiểu hay không (trang trước đó đã ở mức tối thiểu và đã được tải lại sẽ vẫn ở mức tối thiểu nếu chiều cao nội dung là lớn hơn chiều cao khung nhìn).

Khi trang ở mức tối thiểu, Brim sẽ tắt tính năng cuộn tài liệu (nó thực hiện việc này theo cách an toàn không ảnh hưởng đến nội dung của thành phần chính). Vô hiệu hóa cuộn tài liệu ngăn ngừa vô tình để lại ui tối thiểu khi cuộn lên trên. Theo thông số kỹ thuật iOS 7.1 ban đầu, nhấn vào thanh trên cùng sẽ mang lại phần còn lại của chrome.

Kết quả cuối cùng trông như thế này:

Brim trong trình giả lập iOS.

Vì mục đích tài liệu và trong trường hợp bạn muốn viết bản triển khai của riêng mình, điều đáng chú ý là bạn không thể sử dụng Scream để phát hiện nếu thiết bị ở mức tối thiểu ngay sau sự kiện trao đổi định hướngwindowkích thước không phản ánh hướng mới cho đến khi hoạt hình xoay đã kết thúc. Bạn cần phải đính kèm một người nghe đến orientationchangeend sự kiện.

Screamdirectionchangeend đã được phát triển như một phần của dự án này.


3
Đây là cách mở rộng hơn câu trả lời ban đầu của tôi, được đánh dấu là câu trả lời mới cho đến khi có giải pháp tốt hơn nữa :)
bitinn

4
Có vẻ tốt đẹp! Tôi có thể buộc tối thiểu ui mà không cần cuộn ban đầu không?
INT

50
Đây thực sự là câu chuyện không bao giờ kết thúc. Tôi là nhà phát triển trò chơi bằng HTML và tối thiểu trong iOS 7.1 hoạt động tốt - đó là cách duy nhất để ứng dụng chạy toàn màn hình VÀ đồng thời có thể chạm vào phía dưới màn hình. Các giải pháp với thao tác vuốt trang là tốt, nhưng không đủ tốt :( Apple, chúng tôi cần triển khai API toàn màn hình cho các trò chơi, vui lòng.
Petr Urban

4
@Petr: Tôi không thể đồng ý nhiều hơn. Khi bản sửa lỗi này được công bố vào 7.1, chúng tôi đã nhanh chóng đưa ra một luồng mua hàng thanh toán mới đã ghim CTA chính xuống dưới cùng của màn hình .. điều này đã hoạt động và chuyển đổi rất tốt! Nó cảm thấy rất "bản địa" và liền mạch. Mà tôi nghĩ là vấn đề chính xác. Nếu bạn nghĩ về nó, đó không phải là lợi ích tốt nhất của Táo để các ứng dụng web cảm thấy tự nhiên. Trên thực tế, đây là một xung đột lợi ích trực tiếp với sự độc quyền trên App Store của họ. Đây là, IMO, lý do duy nhất hợp lệ tại sao một tính năng có ý nghĩa rất lớn đã được sửa chữa và sau đó cố ý xóa. # my2Cents :)
Jose Browne

2
@PetrUrban Tôi tin chắc rằng Apple sẽ thích bạn xuất bản trò chơi của bạn dưới dạng một ứng dụng phonegap hơn là cho phép bạn phục vụ qua web. Quyết định gần đây của họ cho phép chặn quảng cáo cho safari xi măng ý tưởng này.
Patrick Gunderson

20

Vì không có cách lập trình để bắt chước minimal-ui, chúng tôi đã đưa ra một cách giải quyết khác, sử dụng calc()và biết chiều cao thanh địa chỉ iOS để lợi thế của chúng tôi:

Trang demo sau ( cũng có sẵn trên ý chính, có nhiều chi tiết kỹ thuật hơn ) sẽ nhắc người dùng cuộn, sau đó kích hoạt toàn màn hình mềm (ẩn thanh / menu địa chỉ), trong đó tiêu đề và nội dung sẽ lấp đầy khung nhìn mới.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Scroll Test</title>

    <style>
        html, body {
            height: 100%;
        }

        html {
            background-color: red;
        }

        body {
            background-color: blue;
            margin: 0;
        }

        div.header {
            width: 100%;
            height: 40px;
            background-color: green;
            overflow: hidden;
        }

        div.content {
            height: 100%;
            height: calc(100% - 40px);
            width: 100%;
            background-color: purple;
            overflow: hidden;
        }

        div.cover {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 100;
            width: 100%;
            height: 100%;
            overflow: hidden;
            background-color: rgba(0, 0, 0, 0.5);
            color: #fff;
            display: none;
        }

        @media screen and (width: 320px) {
            html {
                height: calc(100% + 72px);
            }

            div.cover {
                display: block;
            }
        }
    </style>
    <script>
        var timeout;

        window.addEventListener('scroll', function(ev) {

            if (timeout) {
                clearTimeout(timeout);
            }

            timeout = setTimeout(function() {

                if (window.scrollY > 0) {
                    var cover = document.querySelector('div.cover');
                    cover.style.display = 'none';
                }

            }, 200);

        });
    </script>
</head>
<body>

    <div class="header">
        <p>header</p>
    </div>
    <div class="content">
        <p>content</p>
    </div>
    <div class="cover">
        <p>scroll to soft fullscreen</p>
    </div>

</body>
</html>

10

Chỉ cần nói lời tạm biệt với tối thiểu (bây giờ)

Điều đó đúng, minimal-uicó thể vừa hữu ích vừa có hại và tôi cho rằng sự đánh đổi bây giờ có một sự cân bằng khác, có lợi cho những chiếc iPhone mới hơn, lớn hơn.

Tôi đã xử lý vấn đề này khi làm việc với khung js của mình cho các ứng dụng HTML5. Sau nhiều lần thử các giải pháp, mỗi nhược điểm của chúng, tôi đã đầu hàng khi xem xét rằng không gian bị mất trên iPhone trước 6. Với tình huống này, tôi nghĩ rằng hành vi vững chắc và có thể dự đoán được là hành vi được xác định trước.

Nói tóm lại, cuối cùng tôi đã ngăn chặn mọi hình thức tối thiểu , vì vậy ít nhất chiều cao màn hình của tôi luôn giống nhau và bạn luôn biết bạn có không gian thực tế nào cho ứng dụng của mình.

Với sự giúp đỡ của thời gian, đủ người dùng sẽ có nhiều phòng hơn.


BIÊN TẬP

Làm thế nào tôi làm điều đó

Đây là một chút đơn giản, cho mục đích demo, nhưng sẽ làm việc cho bạn. Giả sử bạn có một container chính

html, body, #main {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
.view {
  width: 100%;
  height: 100%;
  overflow: scroll;
}

Sau đó:

  1. sau đó với js, tôi đặt #mainchiều cao của chiều cao của cửa sổ. Điều này cũng giúp xử lý các lỗi cuộn khác được tìm thấy trong cả iOS và Android. Nó cũng có nghĩa là bạn cần phải giải quyết cách cập nhật nó, chỉ cần lưu ý rằng;

  2. Tôi chặn cuộn quá mức khi đạt đến ranh giới của cuộn. Mã này sâu hơn một chút trong mã của tôi, nhưng tôi nghĩ bạn cũng có thể làm theo nguyên tắc của câu trả lời này cho chức năng cơ bản. Tôi nghĩ rằng nó có thể flickr một chút, nhưng sẽ làm công việc.


Xem bản demo (trên iPhone)

Là một sidenote: ứng dụng này cũng có thể đánh dấu được, vì nó sử dụng định tuyến nội bộ đến các địa chỉ được băm, nhưng tôi cũng đã thêm một lời nhắc người dùng iOS để thêm vào nhà. Tôi cảm thấy cách này giúp trung thành và trả lại khách truy cập (và do đó, không gian bị mất đã trở lại).


Để vô hiệu hóa tối thiểu có vẻ rất hợp lý với tôi. Xin vui lòng, bao gồm mô tả ngắn để làm điều đó!
István Pálinkás

Bạn nói đúng, tôi đã thêm một chút cách làm. Nhiều cách khác sẽ làm việc.
Francesco Frapporti

1
Bản demo của bạn không hoạt động trên iOS8, theo iPhone 5.
dmr07

Cảm ơn bạn đã cho tôi biết, nó phải là một số cập nhật vì nó được sử dụng để làm việc. Bạn đang ở safari? Bạn có ý nghĩa chính xác với nó không hoạt động?
Francesco Frapporti

7

Cách dễ nhất tôi tìm thấy để khắc phục điều này là đặt chiều cao của thân máy và các yếu tố html thành 100,1% cho bất kỳ yêu cầu nào mà tác nhân người dùng là iphone. Điều này chỉ hoạt động trong chế độ Phong cảnh, nhưng đó là tất cả những gì tôi cần.

html.iphone, 
html.iphone body { height: 100.1%; }

Hãy xem thử tại https://www.360jungle.com/virtual-tour/25


Cảm ơn @Stephen. chiều cao: 100,1% giúp tôi. Tuy nhiên, khi tôi mở 360jungle.com/virtual-tour/25 trên iPhone (iOS 11.1.1) Safari và nhấp vào các nút ở phía dưới, thanh địa chỉ và thanh công cụ xuất hiện. Điều này là do các nút quá gần cuối màn hình. Tôi đoán sẽ tốt hơn nếu di chuyển chúng đến một nơi khác trên chế độ di động.
Téwa

2

Vấn đề gốc ở đây dường như là safari iOS8 sẽ không ẩn thanh địa chỉ khi cuộn xuống nếu nội dung bằng hoặc nhỏ hơn chế độ xem.

Như bạn đã biết, việc thêm một số phần đệm ở phía dưới sẽ giải quyết vấn đề này:

html {
    /* enough space to scroll up to get fullscreen on iOS8 */
    padding-bottom: 80px;
}
// sort of emulate safari's "bounce back to top" scroll
window.addEventListener('scroll', function(ev) {
    // avoids scrolling when the focused element is e.g. an input
    if (
        !document.activeElement
        || document.activeElement === document.body
    ) {
        document.body.scrollIntoViewIfNeeded(true);
    }
});

Các css trên nên được áp dụng có điều kiện, ví dụ với UA đánh hơi thêm một gt-ios8lớp vào <html>.


1
Chính xác thì JS này làm gì?
Ben Sinclair

Nếu bạn đang đề cập đến scrollIntoViewIfNeeded, thì đó là một dẫn xuất không chuẩn của scrollIntoView( developer.mozilla.org/en-US/docs/Web/API/Euity.scrollIntoView ). Như tên ngụ ý, phương thức cuộn phần tử vào dạng xem. truetham số nói để căn chỉnh khung nhìn với đỉnh của phần tử. Điều này có hiệu lực sẽ ngăn bạn cuộn. Việc thực hiện là thiếu sót mặc dù.
Gajus

1

Tôi muốn bình luận / trả lời một phần / chia sẻ suy nghĩ của tôi. Tôi đang sử dụng kỹ thuật cuộn tràn: y cho một dự án lớn sắp tới của tôi. Sử dụng nó có hai lợi thế CHÍNH.

a) Bạn có thể sử dụng ngăn kéo có các nút hành động từ phía dưới màn hình; nếu tài liệu cuộn và thanh dưới cùng biến mất, chạm vào nút nằm ở dưới cùng của màn hình trước tiên sẽ làm thanh dưới cùng xuất hiện, sau đó có thể nhấp được. Ngoài ra, cách thức hoạt động của điều này, gây rắc rối với các phương thức có nút ở phía dưới cùng.

b) Khi sử dụng phần tử bị tràn, những thứ duy nhất được sơn lại trong trường hợp thay đổi css chính là những phần tử trong màn hình có thể xem được. Điều này mang lại cho tôi một hiệu suất rất lớn khi sử dụng javascript để thay đổi css của nhiều yếu tố một cách nhanh chóng. Ví dụ: nếu bạn có một danh sách 20 yếu tố bạn cần sơn lại và chỉ có hai yếu tố trên màn hình trong phần tử bị tràn, chỉ những phần tử được sơn lại trong khi phần còn lại được sơn lại khi cuộn. Không có nó, tất cả 20 yếu tố được sơn lại.

Tất nhiên, nó phụ thuộc vào dự án và nếu bạn cần bất kỳ chức năng nào tôi đã đề cập. Google sử dụng các yếu tố tràn cho gmail để sử dụng chức năng tôi đã mô tả trên a). Imo, nó đáng để sử dụng, thậm chí xem xét chiều cao nhỏ trong các điện thoại cũ hơn (372px như bạn đã nói).


1

Có thể, sử dụng một cái gì đó giống như ví dụ dưới đây mà tôi đã kết hợp với sự trợ giúp của công việc từ ( https://gist.github.com/bitinn/1700068a276fb29740a7 ) không hoạt động tốt trên iOS 11:

Đây là mã sửa đổi hoạt động trên iOS 11.03, vui lòng nhận xét nếu nó hoạt động cho bạn.

Điều quan trọng là thêm một số kích thước vào BODY để trình duyệt có thể cuộn, ví dụ: height: calc (100% + 40px);

Mẫu đầy đủ bên dưới & liên kết để xem trong trình duyệt của bạn (vui lòng kiểm tra!)

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CodeHots iOS WebApp Minimal UI via Scroll Test</title>

    <style>
        html, body {
            height: 100%;
        }
        html {
            background-color: red;
        }
        body {
            background-color: blue;
            /* important to allow page to scroll */
            height: calc(100% + 40px);
            margin: 0;
        }
        div.header {
            width: 100%;
            height: 40px;
            background-color: green;
            overflow: hidden;
        }
        div.content {
            height: 100%;
            height: calc(100% - 40px);
            width: 100%;
            background-color: purple;
            overflow: hidden;
        }
        div.cover {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 100;
            width: 100%;
            height: 100%;
            overflow: hidden;
            background-color: rgba(0, 0, 0, 0.5);
            color: #fff;
            display: none;
        }
        @media screen and (width: 320px) {
            html {
                height: calc(100% + 72px);
            }
            div.cover {
                display: block;
            }
        }
    </style>
    <script>
        var timeout;

        function interceptTouchMove(){
            // and disable the touchmove features 
            window.addEventListener("touchmove", (event)=>{
                if (!event.target.classList.contains('scrollable')) {
                    // no more scrolling
                    event.preventDefault();
                }
            }, false); 
        }

        function scrollDetect(event){
            // wait for the result to settle
            if( timeout ) clearTimeout(timeout);

            timeout = setTimeout(function() {
                console.log( 'scrolled up detected..' );
                if (window.scrollY > 35) {
                    console.log( ' .. moved up enough to go into minimal UI mode. cover off and locking touchmove!');
                    // hide the fixed scroll-cover
                    var cover = document.querySelector('div.cover');
                    cover.style.display = 'none';

                    // push back down to designated start-point. (as it sometimes overscrolls (this is jQuery implementation I used))
                    window.scrollY = 40;

                    // and disable the touchmove features 
                    interceptTouchMove();

                    // turn off scroll checker
                    window.removeEventListener('scroll', scrollDetect );                
                }
            }, 200);            
        }

        // listen to scroll to know when in minimal-ui mode.
        window.addEventListener('scroll', scrollDetect, false );
    </script>
</head>
<body>

    <div class="header">
        <p>header zone</p>
    </div>
    <div class="content">
        <p>content</p>
    </div>
    <div class="cover">
        <p>scroll to soft fullscreen</p>
    </div>

</body>

Liên kết ví dụ đầy đủ ở đây: https://repos.codehot.tech/misc/ios-webapp-example2.html


1

Có thể để một ứng dụng web chạy ở chế độ toàn màn hình trong cả iOS và Android, nó được gọi là PWA và sau khi làm việc chăm chỉ, đó là cách duy nhất xoay quanh vấn đề này.

PWAs mở ra một số tùy chọn thú vị để phát triển không nên bỏ qua. Tôi đã thực hiện một cặp vợ chồng, hãy xem Hướng dẫn đấu thầu công khai và riêng tư này dành cho nhà thiết kế (tiếng Tây Ban Nha). Và đây là một lời giải thích bằng tiếng Anh từ trang web CosmicJS


-2

Tôi chưa thực hiện thiết kế web cho iOS nhưng từ những gì tôi nhớ đã thấy trong các phiên WWDC và trong tài liệu, thanh tìm kiếm trong Mobile Safari và thanh điều hướng trên HĐH, giờ đây sẽ tự động thay đổi kích thước và thu nhỏ để hiển thị thêm nội dung của bạn.

Bạn có thể kiểm tra điều này trong Safari trên iPhone và lưu ý rằng, khi bạn cuộn xuống để xem thêm nội dung trên một trang, thanh điều hướng / tìm kiếm sẽ tự động bị ẩn.

Có lẽ để nguyên thanh địa chỉ / thanh điều hướng và không tạo ra trải nghiệm toàn màn hình là điều tốt nhất. Tôi không thấy Apple làm điều đó bất cứ lúc nào sớm. Và nhiều nhất họ không tự động kiểm soát khi thanh địa chỉ hiển thị / ẩn.

Chắc chắn, bạn đang mất bất động sản màn hình, đặc biệt là trên iPhone 4 hoặc 4S, nhưng dường như không có sự thay thế nào như Beta 4.


1
Tôi biết tính năng này của iOS7 +, nhưng hãy xem giải thích của tôi ở trên: vì chiều cao của tài liệu hoàn toàn giống với chế độ xem trình duyệt, trình duyệt di động sẽ không ẩn thanh địa chỉ / menu điều hướng , vì không có cuộn nào diễn ra ở cấp độ tài liệu.
bitinn

1
Đây có thể là một hạn chế khi Beta 4 đã loại bỏ tính năng đó. Có thể và có khả năng Apple đang tự động kiểm soát thanh địa chỉ và ngăn các nhà phát triển truy cập vào nó.
iFeli

8
I haven't done web design for iOS- nếu bạn đang thiết kế web, bạn sẽ làm nó cho mọi nền tảng. Bởi vì web là trên mọi nền tảng.
Vấn

4
@Sumit Tôi biết rằng làm việc trên web là phổ biến, nhưng mỗi trình duyệt và các khung cơ bản của chúng có các thuộc tính CSS cụ thể. Vì vậy, Chrome có thể có một số thuộc tính không có sẵn cho Safari và FireFox và ngược lại.
iFeli
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.