jQuery/JavaScript: accessing contents of an iframe
我想使用jquery在iframe中操纵HTML。
我想我可以通过将jquery函数的上下文设置为iframe的文档来做到这一点,比如:
1 2 3 | $(function(){ //document ready $('some selector', frames['nameOfMyIframe'].document).doStuff() }); |
但这似乎不起作用。稍微检查一下,我发现
有人知道这方面的工作吗?
如果
1 | $("#iFrame").contents().find("#someDiv").removeClass("hidden"); |
参考文献
我认为你所做的是受同一原产地政策的约束。这应该是您获得拒绝权限类型错误的原因。
1 2 3 4 5 | $(document).ready(function(){ $('#frameID').load(function(){ $('#frameID').contents().find('body').html('Hey, i`ve changed content of <body>! Yay!!!'); }); }); |
如果iframe-src来自另一个域,您仍然可以这样做。您需要将外部页面读取到PHP中,并将其从域中回送。这样地:
iFrimaPay.PHP1 2 3 4 5 6 7 | <?php $URL ="http://external.com" $domain = file_get_contents($URL) echo $domain ?> |
然后像这样:
显示页面.html1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <html> <head> Test </head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"> $(document).ready(function(){ cleanit = setInterval ("cleaning()", 500 ); }); function cleaning(){ if($('#frametest').contents().find('.selector').html() =="somthing"){ clearInterval(cleanit); $('#selector').contents().find('.Link').html('ideate tech'); } } <body> <iframe name="frametest" id="frametest" src="http://yourdomain.com/iframe_page.php"></iframe> </body> </html> |
上面的例子说明了如何通过iframe在不拒绝访问等情况下编辑外部页面。
使用
1 | iframe.contentWindow.document |
而不是
1 | iframe.contentDocument |
我觉得这样更干净:
1 2 | var $iframe = $("#iframeID").contents(); $iframe.find('selector'); |
您需要将事件附加到iframe的onload处理程序,并在其中执行JS,以便确保iframe在访问它之前已经完成加载。
1 2 3 4 5 | $().ready(function () { $("#iframeID").ready(function () { //The function below executes once the iframe has finished loading $('some selector', frames['nameOfMyIframe'].document).doStuff(); }); }; |
以上将解决"尚未加载"的问题,但在权限方面,如果您在iframe中加载来自不同域的页面,则由于安全限制,您将无法访问该页面。
您可以使用window.postmessage在page和其iframe之间调用函数(是否跨域)。
文档
页面HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <!DOCTYPE html> <html> <head> Page with an iframe <meta charset="UTF-8" /> <script src="http://code.jquery.com/jquery-1.10.2.min.js"> var Page = { id:'page', variable:'This is the page.' }; $(window).on('message', function(e) { var event = e.originalEvent; if(window.console) { console.log(event); } alert(event.origin + ' ' + event.data); }); function iframeReady(iframe) { if(iframe.contentWindow.postMessage) { iframe.contentWindow.postMessage('Hello ' + Page.id, '*'); } } </head> <body> Page with an iframe <iframe src="iframe.html" onload="iframeReady(this);"></iframe> </body> </html> |
IfRAM.HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <!DOCTYPE html> <html> <head> iframe <meta charset="UTF-8" /> <script src="http://code.jquery.com/jquery-1.10.2.min.js"> var Page = { id:'iframe', variable:'The iframe.' }; $(window).on('message', function(e) { var event = e.originalEvent; if(window.console) { console.log(event); } alert(event.origin + ' ' + event.data); }); $(window).on('load', function() { if(window.parent.postMessage) { window.parent.postMessage('Hello ' + Page.id, '*'); } }); </head> <body> iframe <p> It's the iframe. </p> </body> </html> |
我更喜欢使用其他变体进行访问。从父级可以访问子iframe中的变量。
例如,
但是,它在FF中不起作用。为了获得更好的兼容性,您应该使用
我创建了一个示例代码。现在你可以很容易地从不同的域中理解你不能访问iframe.的内容。相同的域,我们可以访问iframe内容
我和你分享我的代码,请运行这个代码检查控制台。我在控制台上打印图像SRC。有四个iframe,两个iframe来自同一个域,另外两个来自其他域(第三方)。您可以看到两个image src(https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif
和
https://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-51545560611975168-hp2x.gif网站)在控制台上也可以看到两个权限错误(二错误:访问属性"document"的权限被拒绝
…irstchild),contents:函数(a)返回m.nodename(a,"iframe")?A.内容文档…
)来自第三方iframe。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top"> <p> iframe from same domain </p> <iframe frameborder="0" scrolling="no" width="500" height="500" src="iframe.html" name="imgbox" class="iView"> </iframe> <p> iframe from same domain </p> <iframe frameborder="0" scrolling="no" width="500" height="500" src="iframe2.html" name="imgbox" class="iView1"> </iframe> <p> iframe from different domain </p> <iframe frameborder="0" scrolling="no" width="500" height="500" src="https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif" name="imgbox" class="iView2"> </iframe> <p> iframe from different domain </p> <iframe frameborder="0" scrolling="no" width="500" height="500" src="http://d1rmo5dfr7fx8e.cloudfront.net/" name="imgbox" class="iView3"> </iframe> <script type='text/javascript'> $(document).ready(function(){ setTimeout(function(){ var src = $('.iView').contents().find(".shrinkToFit").attr('src'); console.log(src); }, 2000); setTimeout(function(){ var src = $('.iView1').contents().find(".shrinkToFit").attr('src'); console.log(src); }, 3000); setTimeout(function(){ var src = $('.iView2').contents().find(".shrinkToFit").attr('src'); console.log(src); }, 3000); setTimeout(function(){ var src = $('.iView3').contents().find("img").attr('src'); console.log(src); }, 3000); }) </body> |
您是否尝试过使用jquery的builtin ready函数等待加载完成的经典方法?
1 2 3 | $(document).ready(function() { $('some selector', frames['nameOfMyIframe'].document).doStuff() } ); |
K
此解决方案的工作原理与iframe相同。我创建了一个PHP脚本,可以从其他网站获取所有内容,最重要的部分是您可以轻松地将自定义jquery应用到外部内容。请参考以下脚本,该脚本可以从其他网站获取所有内容,然后您也可以应用CUSOM jquery/js。此内容可以在任何地方、任何元素或任何页面内使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <?php /* Use below function to display final HTML inside this div */ //Display Frame echo displayFrame(); ?> <?php /* Function to display frame from another domain */ function displayFrame() { $webUrl = 'http://[external-web-domain.com]/'; //Get HTML from the URL $content = file_get_contents($webUrl); //Add custom JS to returned HTML content $customJS =" /* Here I am writing a sample jQuery to hide the navigation menu You can write your own jQuery for this content */ //Hide Navigation bar jQuery(".navbar.navbar-default").hide(); "; //Append Custom JS with HTML $html = $content . $customJS; //Return customized HTML return $html; } |
我最终在这里寻找没有jquery的iframe的内容,所以对于任何其他寻找这个的人来说,它只是:
1 | document.querySelector('iframe[name=iframename]').contentDocument |
为了更加坚固:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | function getIframeWindow(iframe_object) { var doc; if (iframe_object.contentWindow) { return iframe_object.contentWindow; } if (iframe_object.window) { return iframe_object.window; } if (!doc && iframe_object.contentDocument) { doc = iframe_object.contentDocument; } if (!doc && iframe_object.document) { doc = iframe_object.document; } if (doc && doc.defaultView) { return doc.defaultView; } if (doc && doc.parentWindow) { return doc.parentWindow; } return undefined; } |
和
1 2 3 4 5 6 7 8 | ... var frame_win = getIframeWindow( frames['nameOfMyIframe'] ); if (frame_win) { $(frame_win.contentDocument || frame_win.document).find('some selector').doStuff(); ... } ... |