Başka bir etki alanından bir iframe'i nasıl yeniden boyutlandırırım
-Düzenle
Bazı çözümler için aşağı kaydırın .. veya bunun nasıl YAPILMAMASI gerektiğini okuyun: D
Saatler süren kod hacklemesinden sonra sonuç, iframe içindeki hiçbir şeye, alanımda işleyen kaydırma çubuklarına bile erişilemiyor. Pek çok tekniği boşuna denedim.
Size zaman kazandırmak için, bu yola girmeyin bile, etki alanları arası iletişim için sendMessages'ı kullanın. Kullandığım HTML <5 için eklentiler var - Güzel bir örnek için aşağıya gidin :)
Son birkaç gündür bir iframe'i bir siteye entegre etmeye çalışıyorum. Diğer taraf geliştirilirken ve API geliştirilirken bu kısa vadeli bir çözümdür (aylar sürebilir ...) Ve bu kısa vadeli bir çözüm olduğu için easyXDM'yi kullanmak istiyoruz - Diğer etki alanına erişimim var ama onlardan bunu yapmalarını istemek yeterince zor p3p başlığını olduğu gibi ekle .....
3 iframe
Bulduğum en yakın çözüm 3 iframe idi - ancak krom ve safarinin aklına geliyor, bu yüzden onu kullanamam.
kromda aç
http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179
Kaydırma çubuklarını ölçün
Formu yeniden boyutlandırmayı denemek ve yeniden boyutlandırmak için kaydırma yüksekliğinin nasıl kullanılacağına dair başka bir gönderi buldum .. teoride iyi çalışıyor ancak iframe kaydırma yüksekliğini kullanarak düzgün bir şekilde uygulayamadım ..
document.body.scrollHeight
Bu açıkça gövde yüksekliğini kullanır (bu özelliklere erişilemiyor% 100, x-domains belge yüksekliğine değil, istemcilerin canvaz görüntülemesine bağlıdır)
İframe yüksekliğini almak için jquery kullanmayı denedim
$('#frameId').Height()
$('#frameId').clientHeight
$('#frameId').scrollHeight
dönüş değerleri chrome ve ie farklıdır - ya da hiç mantıklı değil. Sorun şu ki, çerçevenin içindeki her şey reddediliyor - kaydırma çubuğu bile ...
Hesaplanmış Stiller
Ancak, iframe'in kromunu inceler ve öğelerini incelersem, bladdy bana iframe içindeki belge boyutlarını gösterir (iframe.heigh almak için jquery x-domain kullanarak - erişim reddedildi) Hesaplanan CSS'de hiçbir şey yok
Şimdi, chrome bunu nasıl hesaplıyor? (düzenleme-tarayıcı, tüm bu ayarları hesaplamak için oluşturma motorunu kullanarak sayfayı yeniden oluşturur - ancak alanlar arası sahtekarlığı önlemek için herhangi bir yere eklenmez .. yani ..)
HTML4
HTML4.x spesifikasyonunu okudum ve orada document.element aracılığıyla salt okunur değerlerin gösterilmesi gerektiğini söylüyor ancak erişimi jquery aracılığıyla reddedildi
Proxy Çerçeve
Bir kullanıcı iframe aracılığıyla oturum açana ve proxy gerçek içerik yerine bir oturum açma sayfası alana kadar, siteye geri vekaletname verip hangisinin sorun olmadığını hesaplama yoluna gittim. Ayrıca bazılarının sayfayı iki kez araması kabul edilemez
http://www.codeproject.com/KB/aspnet/asproxy.aspx
http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/
Sayfayı yeniden işleyin
Bu kadar ileri gitmedim ama kaynağa bakacak ve sayfayı kaynak dosyaya göre yeniden işleyecek jscript motorları var. ancak bu jscript'lerin hacklenmesini gerektirir .. ve bu ticari varlıklar için ideal bir durum değildir ... ve bazı invole pure java applet'leri veya server side render
http://en.wikipedia.org/wiki/Server-side_JavaScript
http://htmlunit.sourceforge.net/ <-java, jscript değil
09-2013 GÜNCELLEMESİNİ DÜZENLE
Bütün bunlar HTML5 soketleriyle yapılabilir. Ancak easyXDM, HTML5 dışı şikayet sayfaları için harika bir yedektir.
1. Çözüm Çok Harika Çözüm!
EasyXDM'yi kullanma
Sunucunuzda şu şekilde bir sayfa kurarsınız
<html>
<head>
<script src="scripts/easyXDM.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
var transport = new easyXDM.Socket(/** The configuration */{
remote: "http://www.OTHERDOMAIN.com/resize_intermediate.html?url=testpages/resized_iframe_1.html",
//ID of the element to attach the inline frame to
container: "embedded",
onMessage: function (message, origin) {
var settings = message.split(",");
//Use jquery on a masterpage.
//$('iframe').height(settings[0]);
//$('iframe').width(settings[1]);
//The normal solution without jquery if not using any complex pages (default)
this.container.getElementsByTagName("iframe")[0].style.height = settings[0];
this.container.getElementsByTagName("iframe")[0].style.width = settings[1];
}
});
</script>
</head>
<body>
<div id="embedded"></div>
</body>
ve arayanların etki alanında sadece intermiedate_frame html ve easyXDM.js'yi aynı yere eklemeleri gerekir. Bir ana klasör gibi - o zaman göreceli dizinlere veya içerilen bir klasöre yalnızca sizin için erişebilirsiniz.
SEÇENEK 1
Tüm sayfalara komut dosyası eklemek istemiyorsanız, 2. seçeneğe bakın!
Ardından, yeniden boyutlandırmanın gerçekleşmesi için ihtiyacınız olan her sayfanın sonuna basit bir jscript ekleyebilirler. Bu sayfaların her birine easyxdm eklemenize gerek yoktur.
<script type="text/javascript">
window.onload = function(){ parent.socket.postMessage( (parseInt(document.body.clientHeight)) + "," + ( document.body.clientWidth ) ); };
</script>
Gönderdiği parametreleri değiştirdim. Genişliğin düzgün çalışmasını istiyorsanız, diğer alandaki sayfaların, aşağıdakine benzer bir şekilde bir stilde sayfanın genişliğini içermesi gerekir:
<style type="text/css">
html, body {
overflow: hidden;
margin: 0px;
padding: 0px;
background-color: rgb(75,0,85);
color:white;
width:660px
}
a {
color:white;
visited:white;
}
</style>
Bu benim için harika çalışıyor. Genişlik dahil edilmezse, çerçeve biraz tuhaf davranır ve ne olması gerektiğini tahmin etmeye çalışır .. ve ihtiyacınız olursa küçülmez.
SEÇENEK 2
Ara çerçeveyi değişiklik yoklaması için değiştirin
Ara çerçeveniz böyle bir şeye benzemelidir ..
<!doctype html>
<html>
<head>
<title>Frame</title>
<script type="text/javascript" src="easyXDM.js">
</script>
<script type="text/javascript">
var iframe;
var socket = new easyXDM.Socket({
//This is a fallback- not needed in many cases
swf: "easyxdm.swf",
onReady: function(){
iframe = document.createElement("iframe");
iframe.frameBorder = 0;
document.body.appendChild(iframe);
iframe.src = "THE HOST FRAME";
iframe.onchange = messageBack();
},
onMessage: function(url, origin){
iframe.src = url;
}
});
//Probe child.frame for dimensions.
function messageBack(){
socket.postMessage ( iframe.contentDocument.body.clientHeight + "," + iframe.contentDocument.body.clientWidth);
};
//Poll for changes on children every 500ms.
setInterval("messageBack()",500);
</script>
<style type="text/css">
html, body {
overflow: hidden;
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
iframe {
width: 100%;
height: 100%;
border: 0px;
}
</style>
</head>
<body>
</body>
</html>
Aralık, boyutun değişip değişmediğini kontrol etmek için daha verimli hale getirilebilir ve yalnızca boyut değişiklikleri her 500 ms'de bir mesaj gönderme işlemi gerektirmiyorsa gönderilir. Bu kontrolü uygularsanız, yoklamayı 50 ms'ye kadar değiştirebilirsiniz! iyi eğlenceler
Tarayıcılar arasında çalışın ve hızlı. Harika hata ayıklama özellikleri !!
Excellent Work to Sean Kinsey who made the script!!!
2.Çözüm (Çalışıyor ama harika değil)
Yani temel olarak, diğer alanla karşılıklı bir anlaşmanız varsa, mesaj gönderme işini yürütmek için bir kitaplık ekleyebilirsiniz. Eğer diğer alana erişiminiz yoksa .. Daha fazla hack aramaya devam edin - çünkü bulduğum bunları bulamadım veya tam olarak gerekçelendiremedim.
Yani diğer etki alanı bunları içerecek Baş etiketi
<script src="scripts/jquery-1.5.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery.postmessage.min.js" type="text/javascript"></script>
<script src="scripts/club.js" type="text/javascript"></script>
Club.js'de, aramaları yeniden boyutlandırmak için yaptığım ve şunları içeren bazı özel aramalar var
$(document).ready(function () {
var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '' ) ),link;
//Add source url hash to each url to authorise callback when navigating inside the frame.Without this clicking any links will break the communication and no messages will be received
$('a[href]').each(function(){
this.href = this.href + document.location.hash ;
});
//Get the dimensions and send back to calling page.
var h1 = document.body.scrollHeight;
var w1 = document.body.scrollWidth;
$.postMessage({ if_height: h1, if_width: w1 }, parent_url, parent );
});
Ve sayfanız tüm zor işi yapacak ve güzel bir senaryosu var ...
//This is almost like request.querystring used to get the iframe data
function querySt(param, e) {
gy = e.split("&");
for (i = 0; i < gy.length; i++) {
ft = gy[i].split("=");
if (ft[0] == param) {
return ft[1];
}
}
}
$(function () {
// Keep track of the iframe dimensions.
var if_height;
var if_width;
// Pass the parent page URL into the Iframe in a meaningful way (this URL could be
// passed via query string or hard coded into the child page, it depends on your needs).
src = 'http://www.OTHERDOAMIN.co.uk/OTHERSTARTPAGE.htm' + '#' + encodeURIComponent(document.location.href),
// Append the Iframe into the DOM.
iframe = $('<iframe " src="' + src + '" width="100%" height="100%" scrolling="no" frameborder="0"><\/iframe>').appendTo('#iframe');
// Setup a callback to handle the dispatched MessageEvent event. In cases where
// window.postMessage is supported, the passed event will have .data, .origin and
// .source properties. Otherwise, this will only have the .data property.
$.receiveMessage(function (e) {
// Get the height from the passsed data.
//var h = Number(e.data.replace(/.*if_height=(\d+)(?:&|$)/, '$1'));
var h = querySt("if_height", e.data);
var w = querySt("if_width", e.data);
if (!isNaN(h) && h > 0 && h !== if_height) {
// Height has changed, update the iframe.
iframe.height(if_height = h);
}
if (!isNaN(w) && w > 0 && w !== if_width) {
// Height has changed, update the iframe.
iframe.width(if_width = w);
}
//For debugging only really- can remove the next line if you want
$('body').prepend("Recieved" + h + "hX" + w + "w .. ");
// An optional origin URL (Ignored where window.postMessage is unsupported).
//Here you must put the other domain.com name only! This is like an authentication to prevent spoofing and xss attacks!
}, 'http://www.OTHERDOMAIN.co.uk');
});
SEÇENEK 3
Artık, etki alanları arası iFrame'leri yeniden boyutlandırmak için küçük bir JS kitaplığıdır, iFrame'in içinde biraz JavaScript olmasını gerektirir, ancak bu yalnızca 2.8k (765 bayt Gzip'lenmiş) yerel JS'dir ve herhangi bir bağımlılığı yoktur. ve ana sayfa tarafından çağrılana kadar hiçbir şey yapmaz. Bu, diğer insan sistemlerinde hoş bir misafir olduğu anlamına gelir.
Bu kod, DOM değişikliklerini tespit etmek için mutationObserver'ı kullanır ve ayrıca yeniden boyutlandırma olaylarını da arar, böylece iFrame içeriğe göre boyutlandırılır. IE8 + ile çalışır.