Làm cách nào để IFrame được phản hồi trong iOS Safari?


134

Vấn đề là khi bạn phải sử dụng IFrames để chèn nội dung vào một trang web, thì trong thế giới web hiện đại, người ta hy vọng rằng IFrame cũng sẽ phản hồi tốt. Về lý thuyết, nó đơn giản, chỉ đơn giản là người dùng sử dụng <iframe width="100%"></iframe>hoặc đặt độ rộng CSS thành iframe { width: 100%; }tuy nhiên trong thực tế, nó không hoàn toàn đơn giản, nhưng nó có thể.

Nếu iframenội dung phản hồi đầy đủ và có thể tự thay đổi kích thước mà không cần thanh cuộn bên trong, thì iOS Safari sẽ thay đổi kích thước iframemà không có bất kỳ vấn đề thực sự nào.

Nếu bạn xem xét các mã sau đây:

<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=9,10,11" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Iframe Isolation Test</title>

    <style type="text/css" rel="stylesheet">

        #Main {
            padding: 10px;
        }
    </style>
</head>
<body>
    <h1>Iframe Isolation Test 13.17</h1>
    <div id="Main">
        <iframe height="950" width="100%" src="Content.html"></iframe>
    </div>
</body>
</html>

Với Content.html :

<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=9,10,11" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Iframe Isolation Test - Content</title>

    <style type="text/css" rel="stylesheet">

        #Main {
            width: 100%;
            background: #ccc;
        }

    </style>
</head>
<body>
    <div id="Main">
        <div id="ScrolledArea">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc malesuada purus quis commodo convallis. Fusce consectetur mauris eget purus tristique blandit. Nam nec volutpat augue. Aliquam sit amet augue vitae orci fermentum tempor sit amet gravida augue. Pellentesque convallis velit eu malesuada malesuada. Aliquam erat volutpat. Nam sollicitudin nulla nec neque viverra, non suscipit purus tincidunt. Aenean blandit nisi felis, sit amet ornare mi vestibulum ac. Praesent ultrices varius arcu quis fringilla. In vitae dui consequat, rutrum sapien ut, aliquam metus. Proin sit amet porta velit, suscipit dignissim arcu. Cras bibendum tellus eu facilisis sodales. Vestibulum posuere, magna ut iaculis consequat, tortor erat vulputate diam, ut pharetra sapien massa ut magna. Donec massa purus, pharetra sed pellentesque nec, posuere ut velit. Nam venenatis feugiat odio quis tristique. 
        </div>      
    </div>
</body>
</html>

Sau đó, điều này hoạt động mà không có vấn đề trong iOS 7.1 Safari. Bạn có thể thay đổi giữa phong cảnh và chân dung mà không có bất kỳ vấn đề.

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Tuy nhiên, chỉ cần thay đổi Content.html CSS bằng cách thêm:

    #ScrolledArea {
        width: 100%;
        overflow: scroll;
        white-space: nowrap;
        background: #ff0000;
    }

Bạn nhận được điều này:

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Như bạn có thể thấy, mặc dù nội dung Content.html hoàn toàn đáp ứng ( div # ScrolledArea đã overflow: scrollđặt) và chiều rộng iframe là 100% iframe vẫn lấy toàn bộ chiều rộng của div # ScrolledArea như thể tràn không tồn tại. Bản giới thiệu

Trong những trường hợp như thế này, iframenội dung có các vùng cuộn trên đó không, câu hỏi trở thành, làm thế nào để có iframephản hồi, khi nội dung iframe có các vùng cuộn theo chiều ngang? Vấn đề ở đây không nằm ở chỗ Content.html không phản hồi, mà thực tế là Safari Safari chỉ đơn giản thay đổi kích thước iframe để div#ScrolledAreacó thể hiển thị đầy đủ.


Bạn có thể chia sẻ một liên kết với chúng tôi? Bạn đang nói rằng iOS sẽ mở rộng một iFrame đến toàn bộ chiều rộng của trang bên trong nếu trang bên trong có nội dung có white-space: nowrapkiểu dáng không?
DA.

@DA Tôi đã thêm các bản demo cho cả vấn đề và giải pháp. Và không, white-space: nowrapbản thân nó không phải là vấn đề. Tôi chỉ đơn giản là sử dụng nó để có được một chiều rộng cực đoan div#ScrolledArea. Vấn đề xảy ra khi nội dung IFrame có các vùng có thể cuộn theo chiều ngang trong đó. Nếu đó là trường hợp, Safari Safari chỉ cần bỏ qua các cài đặt chiều rộng của bạn và hiển thị nội dung lỗ hổng và phá vỡ khả năng phản hồi của trang web.
Idra

Hmm ... tôi tự hỏi nếu đó là một 'tính năng'. Sẽ rất khó xử khi có một khu vực có thể cuộn (iFrame) có chứa nội dung có thể cuộn. Đó là một điều rất khó để tương tác trên màn hình cảm ứng.
DA.

@DA Tất nhiên đây là trường hợp cháu gái và những gì bạn nói có thể đúng (phụ thuộc vào việc triển khai, hoạt động cho chúng tôi) và hầu hết các trang web không có các khu vực có thể cuộn theo chiều ngang, nhưng khi bạn ... bạn thậm chí không thể tưởng tượng được tôi đã dành bao nhiêu thời gian cho việc này. Nhưng điều này có thể là một vấn đề ngay cả khi bạn có hình ảnh bị ẩn và cuộn bằng nút hoặc một cái gì đó tương tự.
Idra

Dường như có những câu hỏi liên quan về vấn đề này: stackoverflow.com/questions/5267996/ nam Có vẻ như là một 'tính năng' của safari di động ... nó đang cố gắng đảm bảo rằng nội dung có kích thước theo cách mà người dùng có thể vẫn tương tác với nó Tôi không chắc điều gì sẽ xảy ra nếu bạn có nội dung cuộn trong iframe cuộn ... Safari sẽ diễn giải một thao tác vuốt trong các phần tử cuộn lồng nhau như thế nào?
DA.

Câu trả lời:


289

Giải pháp cho vấn đề này thực sự khá đơn giản và có hai cách để giải quyết nó. Nếu bạn có quyền kiểm soát Content.html thì chỉ cần thay đổi div#ScrolledAreađộ rộng CSS thành:

        width: 1px;
        min-width: 100%;
        *width: 100%;

Về cơ bản, ý tưởng ở đây rất đơn giản, bạn đặt thành widthmột cái gì đó nhỏ hơn khung nhìn (chiều rộng khung trong trường hợp này) và sau đó ghi đè lên nó min-width: 100%để cho phép thực tế width: 100%mà Safari Safari mặc định ghi đè. Có *width: 100%;mã để tương thích với IE6, nhưng nếu bạn không quan tâm đến IE6, bạn có thể bỏ qua nó. Bản giới thiệu

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Như bạn có thể thấy bây giờ, div#ScrolledAreachiều rộng thực sự là 100% và overflow: scroll;có thể làm điều đó và ẩn nội dung tràn. Nếu bạn có quyền truy cập vào nội dung iframe, thì điều này là thích hợp hơn.

Tuy nhiên, nếu bạn không có quyền truy cập vào nội dung iframe (vì lý do chưa từng có) thì bạn thực sự có thể sử dụng kỹ thuật tương tự trên chính iframe. Chỉ cần sử dụng cùng CSS trên iframe:

    iframe {
        width: 1px;
        min-width: 100%;
        *width: 100%;
    }

Tuy nhiên, có một hạn chế với điều này, bạn cần tắt các thanh cuộn scrolling="no"trên iframe để nó hoạt động:

<iframe height="950" width="100%" scrolling="no" src="Content.html"></iframe>

Nếu thanh cuộn được cho phép, thì thanh này sẽ không hoạt động trên iframe nữa. Điều đó nói rằng, nếu bạn sửa đổi Content.html thay vào đó thì bạn có thể giữ lại cuộn trong iframe. Bản giới thiệu


1
Giống như @NickGottlieb đã đề cập, tôi đã phải thêm !importantvào widththuộc tính để thiết kế web
ifive

@ ЮнгвиртТони Không nên cần thiết cho việc giải quyết cho công việc, nó có thể là widthđã được thiết lập trước đó với !importanthoặc một ưu tiên cao hơn CSS ghi đè lên nó. Trong các trường hợp bị cô lập trong iPhone 4 iOS7 thì không cần thiết.
Idra

Tôi cũng không cần! Hoạt động rất tốt trên iOS 8. Chúc mừng
Sam Potts

Tôi cần cuộn = không chỉ khi cần thiết, nếu không thì cuộn = có. Vậy tôi nên phát hiện cái gì? Đây có phải là một vấn đề iOS? hoặc một vấn đề webkit? hoặc là...?
gerbz

@ggwarpig đây là sự cố iOS, trong đó Safari Safari sẽ tự động bật thuộc tính liền mạch và bạn không thể ghi đè lên nó. Nếu bạn có quyền kiểm soát nội dung, thì bạn cần sửa đổi nội dung để có scrolling="yes"cách khác để khắc phục điều này, để sửa lỗi để hoạt động trên IFRAME, bạn chỉ cần có scrolling="no"trên IFRAME
Idra

24

Vấn đề, có vẻ như là Mobile Safari sẽ từ chối tuân theo chiều rộng của iFrame của bạn nếu tài liệu mà nó chứa rộng hơn những gì bạn đã chỉ định. Thí dụ:

http://jsbin.com/hapituto/1

Trên trình duyệt máy tính để bàn, bạn sẽ thấy cả iFrame và Div đều được đặt thành 300px. Nội dung rộng hơn để bạn có thể cuộn iFrame.

Tuy nhiên, trên safari di động, bạn sẽ nhận thấy iFrame được tự động mở rộng theo chiều rộng của nội dung.

Tôi đoán rằng đây là một cách giải quyết cho các vấn đề tồn tại lâu dài với nội dung cuộn trong một trang. Trước đây, nếu bạn có một iframe cuộn lớn trên thiết bị cảm ứng, bạn sẽ bị 'kẹt' trong iframe vì nó sẽ cuộn thay vì chính trang đó. Có vẻ như Apple đã quyết định rằng hành vi mặc định của iFrame là 'không cuộn' và mở rộng để ngăn chặn hành vi đó.

Một lựa chọn có thể là cách giải quyết này. Thay vì giả sử iFrame sẽ cuộn, hãy đặt iframe trong DIV mà bạn có quyền kiểm soát và để cuộn đó.

ví dụ: http://jsbin.com/zakenaja/1

Đánh dấu ví dụ:

<div style="overflow: scroll; -webkit-overflow-scrolling: touch; width: 300px;">
   <iframe src="http://jsbin.com/roredora/1/" style="width: 600px;"></iframe>
</div>

Trên safari di động, giờ đây bạn có thể cuộn nội dung của iFrame hiện đã được mở rộng hoàn toàn thông qua div có chứa nó.

Lưu ý: Điều này trông thực sự xấu xí trên trình duyệt máy tính để bàn, vì bây giờ bạn có thanh cuộn kép. Vì vậy, bạn có thể phải thực hiện một số phát hiện trình duyệt với JS để khắc phục điều này.


1
Tôi vẫn sẽ bảo đảm rằng điều này không thực sự nằm trong phạm vi của câu hỏi, bởi vì giải pháp bạn đưa ra ở đây là cách tiêu chuẩn để giả mạo cuộn iframe trong iOS Safari, nhưng xem xét vấn đề iOS này là vấn đề liên quan đến cuộn IFrame (nội dung hoặc cách khác) thì thật tuyệt khi có nó ở đây.
Idra

1
Tôi đoán tôi không hiểu hết câu hỏi của bạn. Theo những gì tôi hiểu, vấn đề bạn gặp phải là trong iOS, Mobile Safari cố gắng ngăn iFrame cuộn ở vị trí đầu tiên và buộc chiều rộng của nó. Tôi có hiểu nhầm vấn đề của bạn không?
DA.

Về bản chất đó là vấn đề, nó chỉ là giải pháp cần thiết là khác nhau. Trong vấn đề ban đầu, nội dung IFrame đã phản hồi, trong khi có nội dung cuộn theo chiều ngang nên câu hỏi không phải là làm thế nào để mô phỏng cuộn iframe , mà là làm thế nào để có chiều rộng iframe 100% tức là phản hồi, trong khi bạn có nội dung cuộn theo chiều ngang iframe đó. Đó là lý do tại sao cách tiếp cận trên không hoạt động trong trường hợp này, vì khả năng đáp ứng được thiết kế đã bị hỏng và bạn cần cuộn xung quanh để xem toàn bộ nội dung, ngay cả ở những nơi theo thiết kế mà bạn thường không cần.
Idra

1
Tôi xin lỗi, tôi nhận ra rằng tôi đã đánh lừa bạn về một trong những ý kiến. Khung nội tuyến không cuộn. Đó là điểm chính, iframe không được cho là chỉ cuộn các phần của nội dung của nó, tức là div#ScrolledArea(màu xanh lá cây) trong ví dụ của tôi. Tôi chỉ đọc sai trước đây. Nhưng iframe không nên cuộn chỉ thay đổi kích thước dựa trên phần tử container tức là cówidth: 100%;
Idra

18

Tôi cần một giải pháp đa trình duyệt. Yêu cầu là:

  • cần thiết để hoạt động trên cả iOS và các nơi khác
  • không có quyền truy cập vào nội dung trong iFrame
  • cần nó để cuộn!

Xây dựng những gì tôi học được từ @Idra về việc cuộn = "không" trên iOS và bài đăng này về việc khớp nội dung iFrame với màn hình trong iOS đây là những gì tôi đã kết thúc. Hy vọng nó sẽ giúp được ai đó =)

HTML

<div id="url-wrapper"></div>

CSS

html, body{
    height: 100%;
}

#url-wrapper{
    margin-top: 51px;
    height: 100%;
}

#url-wrapper iframe{
    height: 100%;
    width: 100%;
}

#url-wrapper.ios{
    overflow-y: auto;
    -webkit-overflow-scrolling:touch !important;
    height: 100%;
}

#url-wrapper.ios iframe{
    height: 100%;
    min-width: 100%;
    width: 100px;
    *width: 100%;
}

Mã não

function create_iframe(url){

    var wrapper = jQuery('#url-wrapper');

    if(navigator.userAgent.match(/(iPod|iPhone|iPad)/)){
        wrapper.addClass('ios');
        var scrolling = 'no';
    }else{
        var scrolling = 'yes';
    }

    jQuery('<iframe>', {
        src: url,
        id:  'url',
        frameborder: 0,
        scrolling: scrolling
    }).appendTo(wrapper);

}

1
được nâng cấp, nhưng ... tại sao quy tắc IE6 trong lớp "ios"? :-)
J. Bruni

12

Vấn đề với tất cả các giải pháp này là chiều cao của iframekhông bao giờ thực sự thay đổi.

Điều này có nghĩa là bạn sẽ không thể căn giữa các yếu tố bên trong iframebằng cách sử dụng Javascript position:fixed;hoặc position:absolute;iframebản thân nó không bao giờ cuộn.

Giải pháp của tôi chi tiết ở đây là bọc tất cả nội dung của iframe bên trong divbằng CSS này:

#wrap {
    position: fixed;
    top: 0;
    right:0;
    bottom:0;
    left: 0;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
}

Bằng cách này, Safari tin rằng nội dung không có chiều cao và cho phép bạn chỉ định chiều cao của iframeđúng. Điều này cũng cho phép bạn định vị các yếu tố theo bất kỳ cách nào bạn muốn.

Bạn có thể xem một bản demo nhanh và bẩn ở đây.


1
Đây là giải pháp duy nhất làm việc cho tôi. Tất nhiên, nó chỉ có thể được sử dụng nếu bạn kiểm soát nội dung của iframe, nhưng trong trường hợp của tôi, tôi làm. Chúc mừng!
Vince

Hừm. Ví dụ của bạn dường như không phản hồi trên iOS?
BrandonReid

Đó là 2 năm trước khi tôi viết bài này. Bạn có thể gửi một vấn đề trong repo?
Cầu tàu

sau khi lãng phí hàng giờ liền cho vấn đề này với Ionic / Cordova trên iOS, đây là điều duy nhất có hiệu quả. cảm ơn!
Andrew

1
Điều này thật tuyệt vời, chỉ có một cách hiệu quả, tôi đã dành 1 ngày để tìm kiếm một giải pháp như thế này @Pier 100pts cho bạn
Carlos E

5

Vấn đề này cũng có mặt trên Chrome Chrome.

Tôi liếc qua tất cả các giải pháp trên, hầu hết đều rất hack.

Nếu bạn không cần hỗ trợ cho các trình duyệt cũ hơn, chỉ cần đặt chiều rộng iframe thành 100vw;

iframe {
  max-width: 100%; /* Limits width to 100% of container */
  width: 100vw; /* Sets width to 100% of the viewport width while respecting the max-width above */
}

Lưu ý: Kiểm tra hỗ trợ cho các đơn vị chế độ xem https://caniuse.com/#feat=viewport-units


1
Chrome cho iOS chỉ là Safari bên dưới. Nó sử dụng WKWebView. Không có công cụ kết xuất web nào khác được cho phép trong iOS.
Cầu tàu

3

Tôi đang làm việc với ionic2 và cấu hình hệ thống như dưới đây-


******************************************************

Your system information:

Cordova CLI: 6.4.0 
Ionic Framework Version: 2.0.0-beta.10
Ionic CLI Version: 2.1.8
Ionic App Lib Version: 2.1.4
ios-deploy version: Not installed
ios-sim version: 5.0.8 
OS: OS X Yosemite
Node Version: v6.2.2
Xcode version: Xcode 7.2 Build version 7C68



******************************************************

Đối với tôi, vấn đề này đã được giải quyết với mã này -
đối với thẻ iframe html-

<div class="iframe_container">
      <iframe class= "animated fadeInUp" id="iframe1" [src]='page' frameborder="0" >
        <!--  <img src="img/video-icon.png"> -->
      </iframe><br>
   </div>

Xem css của cùng


.iframe_container {
  overflow: auto; 
  position: relative; 
  -webkit-overflow-scrolling: touch;
  height: 75%;
}

iframe {
  position:relative;
  top: 2%;
  left: 5%;
  border: 0 !important;
  width: 90%;
}

Vị trí tài sản đóng một vai trò quan trọng ở đây trong trường hợp của tôi.
vị trí: tương đối;

Nó cũng có thể giúp bạn !!!


0

Giải pháp chỉ CSS

HTML

<div class="container">
    <div class="h_iframe">
        <iframe  src="//www.youtube.com/embed/9KunP3sZyI0" frameborder="0" allowfullscreen></iframe>
    </div>
</div>

CSS

html,body {
    height:100%;
}
.h_iframe iframe {
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
}

BẢN GIỚI THIỆU

Một bản demo khác ở đây với trang HTML trong iframe


Có thể tôi đang triển khai giải pháp của bạn không chính xác, nhưng khi tôi thử nó với trường hợp thử nghiệm bị cô lập của mình, thì nó không hoạt động, tất cả trong iOS Safari 7.1 iPhone 4. Bạn có thể giải thích cách thức hoạt động của nó không?
Idra

OK, có vẻ như bạn đã hiểu nhầm vấn đề, hãy kiểm tra liên kết này xem đó là nội dung iframe demo mới của bạn được tích hợp mà không có bất kỳ CSS bổ sung nào được áp dụng cho iframe. Và nếu bạn xem nó trong iOS Safari, thì nó vẫn phản hồi, điều này là do trang này không có bất kỳ cuộn ngang nào sẽ buộc chiều rộng iframe rộng hơn khung nhìn. Như được mô tả trong câu hỏi, trên một trang web như thế này, bạn không cần phải làm gì để iframe được phản hồi.
Idra

Vì vậy, chính xác những gì bạn muốn nó hành xử, đưa ra ví dụ cho liên kết đã cho của bạn?
4dgaurav

0

Tôi gặp vấn đề với chiều rộng trên khung nội dung tạo thanh cuộn ngang cho iframe. Hóa ra một hình ảnh đang giữ chiều rộng rộng hơn mong đợi. Tôi đã có thể giải quyết nó bằng cách đặt tất cả các hình ảnh chiều rộng tối đa css thành phần trăm.

<meta name="viewport" content="width=device-width, initial-scale=1" />

img {
        max-width: 100%;
        height:auto;
    }

0

thực tế đối với tôi chỉ làm việc trong ios vô hiệu hóa cuộn

<iframe src="//www.youraddress.com/" scrolling="no"></iframe>

và xử lý HĐH thông qua tập lệnh.


0

Đối với tôi giải pháp CSS không hoạt động. Nhưng thiết lập chiều rộng theo chương trình sẽ thực hiện công việc. Trên tải iframe đặt chiều rộng theo chương trình:

 $('iframe').width('100%');
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.