因为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.οnlοad=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.οnlοad=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.οnlοad=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(查询部分)