Изменение размера проблемы Iframe только в Chrome - PullRequest
2 голосов
/ 27 февраля 2012

Хорошо, здесь идет. Переполнение стека, девственница здесь, но, надеюсь, вы, ребята, сможете мне помочь.

Я пытался изменить высоту фрейма в зависимости от его содержания. Содержание меняется в зависимости от того, как пользователь будет проходить через серию форм, это означает, что каждая отправка приведет к новой форме, в которой есть 3 формы.

Код ниже вызывается при загрузке iframe,

function checkHeight() {
    var frame=document.getElementById('frame');
    var doc=frame.contentWindow.document;
    var data=doc.getElementById('data');
    alert(data);
    var data_height=data.offsetHeight;
    if(data_height) {
        frame.style.height=data_height + 'px';
        alert('height has been set');
    }
}

Это отлично работает на Mac и PC версиях Mozilla, IE и Safari, но у меня возникла серьезная проблема с Chrome. Он не возвращает документ в рамке. Это ошибка разрешений или что ?!

Я также попробовал contentDocument, но безрезультатно.

Все документы находятся на моем сервере и находятся в одной папке.

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 23 марта 2012

Редактировать:

Я перечитал ваш вопрос - было бы проще просто вычислить высоту внутри документа iframe и вызвать родительскую функцию изменения размера, так как они находятся в одной изолированной программной среде безопасности (т.е. включенытот же домен)?

Оригинал:

Поскольку аналогичная ситуация происходит, когда элементы iframe внедряются из другого домена (невозможно получить доступ к iframe..document), я бы предположил, что этот подход будет работать:

  1. Первое: вычислить высоту документа в самом документе (т. Е. Внутри iframe).
  2. Передать значения родительскому элементу, используя window.postMessage / хэш-опрос для старых браузеров.Существует аккуратная библиотека , которая заботится о совместимости для вас.
  3. Получите значение в родительском элементе и измените размер iframe соответственно.

Опять же, это можетбудьте излишними, но, учитывая, что решение было протестировано, чтобы делать именно то, что вы ищете между различными песочницами безопасности , это также должно быть в случае более простого сценария, если iframes находятся в одном домене.

При этом, если они находятся в одном домене (в отличие от виджетов / нерасчлененного стороннего контента), действительно ли нужен iframe?Похоже, это всего лишь вопрос настройки jQuery для выполнения запросов ajax и заполнения контейнеров новыми данными.

1 голос
/ 23 марта 2012

это кажется довольно прямым вопросом, поэтому я не уверен, почему такие странные ответы, поэтому, возможно, я полностью пропустил лодку, но вот мои решения, одно из них - x-domain, а другое - нет (примечание: open / write / close, просто для того, чтобы имитировать взаимодействие с сервером, чтобы сделать более очевидным, что происходит ...)

первый стиль x-домена:

// METHOD #1: postMessage() x-domain (chrome, ff, ie8+, safari, etc)
var d = document,
    iframe = d.createElement('iframe');
iframe.height = 0;
d.getElementsByTagName('body')[0].appendChild(iframe);

window.onmessage = function(msg) { 
  iframe.height = parseInt(msg.data, 10);
};

var fd = iframe.contentDocument || iframe.contentWindow.document;
fd.open();
fd.write('<!DOCTYPE ht' + 'ml><ht' + 'ml><he' + 
         'ad><scri' + 'pt>' +
         'window.onload = function(){' +

         'var db = document.body,' +
         'de = document.documentElement;' +

         'window.parent.postMessage(' + 
           'Math.max(db.scrollHeight, de.scrollHeight, db.offsetHeight, de.offsetHeight, db.clientHeight, de.clientHeight),' +
           '"*"' +
         ');' +

         '};</scr' + 'ipt></he' + 'ad><bo' + 
         'dy style="background:#afa"><div style="border:s' +
         'olid 1px black;padding:50px;line-height:50px">method #1: x-domain<b' +
         'r />test<br />test</div></bo' + 'dy></ht' + 
         'ml>');
fd.close();

следующая более совместимая версия домена:

// METHOD #2: manually same-domain (all browsers? [with tweaks] )

var iframe2 = d.createElement('iframe');

iframe2.height = 0;

iframe2.onload = function() {
  var xfd = iframe2.contentDocument || iframe2.contentWindow.document,
      db = xfd.body,
      de = xfd.documentElement;

  iframe2.height = Math.max(db.scrollHeight, de.scrollHeight, db.offsetHeight, de.offsetHeight, db.clientHeight, de.clientHeight);

};

d.getElementsByTagName('body')[0].appendChild(iframe2);

fd = iframe2.contentDocument || iframe2.contentWindow.document;
fd.open();
fd.write('<!DOCTYPE ht' + 'ml><ht' + 'ml><he' + 
         'ad></he' + 'ad><bo' + 
         'dy style="background:#aaf"><div style="padding:50px;line-height:50px;border:s' +
         'olid 1px black;">method #2: same domain<b' +
         'r />test2<br />test2</div></bo' + 'dy></ht' + 
         'ml>');
fd.close();

Вы можете увидеть это в действии здесь: http://jsbin.com/ifevad

Надеюсь, это поможет -ck

0 голосов
/ 20 марта 2012

Этот тот же самый пример работал для меня, в Chrome 17, на Windows, с заданными html-файлами:

index.html:

<html>
<head>
</head>
<body>
<iframe src="index2.html" id="test">
</iframe>
</body>
</html>

index2.html

<html>
<head>
</head>

<body>
<div id="test_div">
    Ohai
</div>
</body>
</html>

Затем я использовал это в окне разработчика Chrome:

i = document.getElementById('test')
doc = i.contentWindow.document
data=doc.getElementById('test_div');
i.style.height = data.offsetHeight + 'px'

Единственная загвоздка в том, что она не работала при непосредственном открытии файлов .html - мне пришлось запустить веб-сервер. Я использовал это (это сервер Python по умолчанию):

server.py

import SimpleHTTPServer
import SocketServer

PORT = 8080

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...