原生js与iframe一些事

因为sem推广总是提出一些让人吐血的需求,类似于用A链接访问B链接的内容,pc跟无线又要区分不同页面,区域的不同又要显示的内容不同等等,哎呀妈妈喂,净瞎折腾。

这一次的需求是打开A链接,mobile显示B链接的内容,pc显示C链接的内容,因为访问链接不能变。因此我首先想到的就是用iframe了。

本文的前提是iframe同域,即不存在跨域情况,页面没考虑IE兼容

A.html模板大概就是下面酱紫啦:

{if $flag eq 'mobile'}
    <p class="title" style="display: none;">手机端title</p>
    <iframe id="iframe" name="iframe" frameborder="0"  style="width: 100%; height: 1000px; padding: 0; margin: 0" scrolling="auto"></iframe>    
{else}    
    <p class="title" style="display: none;">pc端title</p>
    <iframe id="iframe" name="iframe" frameborder="0"  style="width: 100%; height: 1000px; padding: 0; margin: 0" scrolling="auto"></iframe>
{/if}

pc跟手机判断我就直接用php那边判断了。为什么要这么做呢?我是这么想的:

如果我用js来判断手机跟无线,无非就是隐藏谁显示谁的问题(用这种方法的话,如果pc、手机端页面内容多的话,那么不管显示哪个页面,他都会把所有资源加载出来的,就算你display为none),或者是js里面判断客户端,然后再动态添加src,动态引入资源。哎呀,就是因为后面还要添加很多标签,所以就不用js来写了,省了麻烦。

然后用js动态添加src。如果你的src不需要携带参数的话,那么可以直接把src写在iframe里面。但是我这里因为要有在线咨询的功能,而且需要在url后面添加渠道追踪才能进行咨询(比如www.u-can.cn?channel=27),所以这个src是会变化的,还是贴代码比较清楚,原谅我不是很会表达,哈哈

A.html页面:

window.onload=function(){
       document.title=document.querySelector('.title').innerHTML;
        var ifr=document.querySelector('#iframe');
        var local_search=window.location.search;//这里可以获取到url?及后面的参数
        if(document.querySelector('#iframe')){
                ifr.style.height=window.innerHeight+'px';
                var src1='';             
if(navigator.userAgent.match(/Android|iPhone|SymbianOS|Windows Phone|iPad|iPod/)){
//mobile显示b.html页面内容 src1
='/b.html'; }else{
//pc显示c.html页面内容 src1
='/c.html'; } if(local_search){ // 如果url存在?参数,则把参数传入,例如b.html?参数 ifr.src=src1+local_search; }else{ ifr.src=src1; }
      } }

当你以为一切万事大吉的时候,一堆问题又来了。我这个嵌套的页面有fixed定位的元素,比如有底部固定悬浮按钮呀,右侧悬浮咨询按钮呀,在安卓机、谷歌模拟下都正常显示,但是平常NBHH的苹果家族竟然有问题了。需求方反映说她的iphone6页面下底部按钮被甩在了文章底部。靠,返工重做。

百度一番后,决定把嵌套在页面内的fixed元素全部搬到父页面,模板改成这样:

<!--A.html-->
<
body> {if $flag eq 'mobile'} <p class="title" style="display: none;">mobile title</p> <iframe id="iframe" name="iframe" frameborder="0" style="width: 100%; height: 1000px; padding: 0; margin: 0" scrolling="auto"></iframe> <a class="scroll-top" href="javascript:;">返回顶部</a> <div class="f_nav_box"> <div class="main footer_nav"> <a id="one" class="one" href="javascript:;"><img src="images/images/icon_02.jpg" alt="" >按钮1</a> <a class="three" >按钮2</a> <a id="four" class="four" href="javascript:;" >按钮3</a> </div> </div> {else} <p class="title" style="display: none;">pc title</p> <iframe id="iframe" name="iframe" frameborder="0" style="width: 100%; height: 1000px; padding: 0; margin: 0" scrolling="auto"></iframe> {/if} </body>

好了,现在苹果机上能正常显示fixed定位的按钮了。不过还有两个问题需要解决:

  1. 当页面滑动高度大于500时,显示返回顶部按钮,点击返回顶部按钮,页面回到最顶部
  2. 页面底部固定按钮1点击跳转锚点1,按钮3跳转锚点2,并让某一个复选框被勾选(这里就模拟下调用b页面的fun1函数)

解决1:

A.html页面:

window.onload=function(){
      var ifr=document.querySelector('#iframe');
      var to_top=document.querySelector('.scroll-top');
//操作iframe还是需要在它加载完后再进行吧,不然直接操作会返回undefined的 ifr.onload
=function(){ var ifr_window=window.frames["iframe"]||ifr.contentWindow;//获取iframe窗口 var ifr_doc= ifr_window.document;//获取iframe文档---console控制台打印输出显示<html></html>所有内容 // ifr_doc.querySelector('.floattel').style.display='none';//这样就可以操作iframe里面的元素了 // ifr_doc.querySelector('.footer').style.paddingBottom='6em';
//给iframe页面添加滚动事件 ifr_window.onscroll
=function(){ var scrollTop = ifr_doc.body.scrollTop;//获取文档内滚动条滚动高度 if(!to_top) return; if(scrollTop>500){//当高度大于500时,显示返回顶部按钮,否则隐藏 to_top.style.display='block'; }else{ to_top.style.display='none'; } }; if(to_top){
//给返回顶部按钮注册点击事件--iframe窗体
scrollTo(0,0)

to_top.onclick=function(){
                   ifr.contentWindow.scrollTo(0,0);
}; } } }

备注:后面测试后才发现安卓及可以正常显示返回顶部按钮,但是苹果机下不行。查了一些资料后了解到ios系统不能再在iframe框架页面触发onscroll事件,额。。。所以后面就不用这种写法了

解决2:

A.html页面:

window.onload=function(){
        var ifr=document.querySelector('#iframe');
        var one=document.querySelector('#one');
        var four=document.querySelector('#four');
         ifr.onload=function(){
                var ifr_window=window.frames["iframe"]||ifr.contentWindow;
                var ifr_doc= ifr_window.document;
                 one.onclick=function(){
                       ifr_window.location.hash='#sdly';//跳到b页面指定锚点
                       ifr_window.location = ifr_window.location;
                  };
                  four.onclick=function(){
                        ifr_window.location.hash='#order';//跳到b页面指定锚点
                        ifr_window.location = ifr_window.location;
ifr_window.fun1();//调用b页面定义的fun1方法 }; } }

B.html页面:

<html>
<head>
    <title></title>
</head>
<body>
<div id="sdly">点击父窗口按钮1跳到这里</div>
<div id="order">点击父窗口按钮3跳到这里并执行fun1()</div>
<script>
      function fun1(){
           alert('我是点击父窗口的按钮触发的!');
       }

</script>
</body>
</html>

说明:

ifr_window.location.hash='#order';//跳到b页面指定锚点
ifr_window.location = ifr_window.location;
在锚点跳转这里我在hash后面还添加了
ifr_window.location = ifr_window.location;这串代码。因为测试的时候发现谷歌只响应第一次锚点跳转,后面再次点击就没有反应了,所以加上这一句后就正常了。
最后这里记录下window.location的相关知识点:

window.location 对象所包含的属性

属性描述
hash 从井号 (#) 开始的 URL(锚)
host 主机名和当前 URL 的端口号
hostname 当前 URL 的主机名
href 完整的 URL
pathname 当前 URL 的路径部分
port 当前 URL 的端口号
protocol 当前 URL 的协议
search 从问号 (?) 开始的 URL(查询部分)
posted @ 2016-07-06 14:18 U_can 阅读(...) 评论(...) 编辑 收藏