关于iframe刷新仍在当前页面而不跳转到首页

本文介绍了一种通过JavaScript实现的菜单栏动态加载方法,该方法利用cookie缓存iframe节点ID,确保用户刷新页面时能保持在当前页面。同时,菜单项数据从数据库动态获取,实现了菜单栏的灵活配置。

菜单栏主要是两轮加载,但是只要活得nodeid就可以了。

菜单中的数据就是从数据库中获取的,不是写死的,对应的nodeid。

这个主要就是采用cookie缓存iframe的nodeid节点。

主要的代码如下:

$(document).ready(function() {
	var indexurl=window.location.href;
	if(indexurl.indexOf("#") > 0) {
		var strcookie=document.cookie;
		var menu_n1="";
		var menu_n2="";
		if (strcookie.length > 0) {
			var arrcookie=strcookie.split(";");
			for(var i=0; i<arrcookie.length; i++){
				var arrvalue=arrcookie[i].split("=");
				var keyname=arrvalue[0].trim();
				if(keyname == "menu_n1") {
					menu_n1=arrvalue[1].trim();
				}else if(keyname == "menu_n2") {
					menu_n2=arrvalue[1].trim();
				}
			}
		}
		init_menu1();
		change_menu(menu_n1, menu_n2);
	}else {
		// 第一次加载
		$("#contentframe").attr("src", "${ctx }/finedo/redirect/index");
	   	init_menu1();
	   	change_menu("${n1}", "${n2}");
	}
});

//data:跳转需要传递的参数,目标页面使用{param.index_transition_data}获取,参数使用^或*分隔
function change_menu(n1,n2,data){
	if(n1){
		menu_1_touch(n1, true);
		if(n2){
			menu_1_touch(n1,data);
		}
	}
}
function init_menu1(){	
    var userrightlist=$.parseJSON('${LOGINDOMAIN_KEY.userrightlist}');
    var arr = userrightlist;
    var j = arr.length;
    for(var i=0;i<j;i++){   
        if(arr[i].parentnodeid=="0"){
        	if("N10"==arr[i].nodeid){
            	$("#sy-nav").append('<li style=\'-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;\' id="li_'+arr[i].nodeid+'" ><a href="javascript:;" id="a_'+arr[i].nodeid+'" onclick="menu_1_touch(\''
       				   +arr[i].nodeid+'\', true)">'+arr[i].nodename+'</a>'
       				   +((arr[i].nodename=='首页')?('<div class="sy-menu" id="li_div_'+arr[i].nodeid+'" style="display: none;"></div>'):'')+'</li>');		   
            	console.log(arr[i].nodeid);
            	}else{
            		 $("#sy-nav").append('<li id="li_'+arr[i].nodeid+'"><a  target="contentframe" style="text-decoration:none;color:#FFFFFF;"  onclick="menu_1_touch(\''
             				   +arr[i].nodeid+'\', true)">'+arr[i].nodename+'</a>'+'<div class="sy-menu" id="li_div_'+arr[i].nodeid+'" style="display: none"></div></li>'); 
               		 init_menu2(arr[i].nodeid);	
            	}	
        	}  
        menu_1_touch("N10",false);
        finedo.message.hideWaiting();
    }
}
function init_menu2(nodeid){    
    var href="";
    var userrightlist=$.parseJSON('${LOGINDOMAIN_KEY.userrightlist}');
    var j = userrightlist.length;
    for(var i=0;i<j;i++){        
         if(userrightlist[i].parentnodeid==nodeid && userrightlist[i].isnavigation=='是'){
                 href=ctx+userrightlist[i].rightentry;
                $("#li_div_"+nodeid).append('<p><a href='+href+' target="contentframe" style="text-decoration:none;color:#FFFFFF;" onclick="menu_1_touch(\''
      				   +userrightlist[i].nodeid+'\', true)">'+userrightlist[i].nodename+'</a></p>');
            }                     
    }
    $("#li_"+nodeid).hover(function(){  
        $("#li_div_"+nodeid).show();  
    },function(){ 
        $("#li_div_"+nodeid).hide();
    }); 
	
} 
function menu_1_touch(nodeid,reloadflag){
	//激励当前页面的数据到cookie,解决刷新回到首页的问题
	document.cookie = "menu_n1="+nodeid;
	history.pushState({},"",window.location.pathname+"#"+nodeid);
	if(nodeid=='N10'){
		//初始化首页
		if(reloadflag){
			$("#contentframe").attr("src",ctx+"/finedo/redirect/index");
		}
		return ;
	}
	var userrightlist=$.parseJSON('${LOGINDOMAIN_KEY.userrightlist}');
	var arr = userrightlist;
	var j = arr.length;
	for(var i =0;i<j;i++){
		
		if(arr[i].nodeid==nodeid){
			$("#contentframe").attr("src",ctx+arr[i].rightentry);
		}	
	}
}

这样子刷新就可以直接在当前页面了。

html页面如下:

<body  >
<!---头部--->
<div class="head">
<div class="com-pad">
   
   <li><img src="${ctx}/syzw_service/include/images/logo.png" /></li>
	<li>		<ul class="sy-nav" style="z-index: 99;" id="sy-nav"></ul></li>
	<li style="float:right;"> <div class="user-info" style="width: 180px;" >
       <div class="userImg" style="float: left; margin-left: 10px;"><img src="${ctx}/syzw_service/include/images/user.png"> </div>
        <span style="display:inline:block; height:40px; line-height:40px;">${sessionScope.LOGINDOMAIN_KEY.sysuser.personname}</span>
        <a style="position: relative;display:block; top:-30px;z-index:999;"  href="${ctx }/finedo/auth/logout">
 			<img style="float:right; display:inline-block; width:30px; margin-left:10px; margin-top:-20px;" src="${ctx}/syzw_service/include/images/exit.png" >
  	 	</a></li>		
   </div>
   </div>
</div> 
<!---头部结束--->

<iframe class="content" src="" id="contentframe" name="contentframe"  frameborder="0" width="100%" scrolling="auto" marginheight="0" marginwidth="0" onLoad="setIframeHeight(this.id)" style="padding-top:60px;"></iframe>
<script type="text/javascript">
function getDocHeight(doc) {
	doc = doc || document;
	var body = doc.body, html = doc.documentElement;
	var height = Math.max( body.scrollHeight, body.offsetHeight, 
        html.clientHeight, html.scrollHeight, html.offsetHeight );
    return height;
}

function setIframeHeight(id) {
	var ifrm = document.getElementById(id);
	var doc = ifrm.contentDocument? ifrm.contentDocument: 
        ifrm.contentWindow.document;
    ifrm.style.visibility = 'hidden';
    ifrm.style.height = "10px"; 
    ifrm.style.height = getDocHeight( doc ) + 4 + "px";
    ifrm.style.visibility = 'visible';
}
</script>
</body>

这样就可以了。
### 防止 iframe 中页面跳转导致父页面刷新的方法 为了防止 `iframe` 内部页面跳转引起父页面的刷新,可以通过 JavaScript 动态监听并控制 `iframe` 的行为。以下是具体的解决方案: #### 方法一:拦截 `iframe` 的导航事件 现代浏览器支持 `beforeunload` 和 `pagehide` 事件,这些事件可以在页面即将卸载时触发。通过绑定这些事件到 `iframe` 上,可以检测其内部是否发生了跳转操作。 ```javascript const iframe = document.querySelector('iframe'); // 绑定 load 事件以确保 iframe 加载完成后执行逻辑 iframe.addEventListener('load', () => { const iframeWindow = iframe.contentWindow; // 如果 iframe 页面支持 postMessage,则可以与其通信 iframeWindow.addEventListener('beforeunload', (event) => { event.preventDefault(); // 阻止默认行为 console.log('Iframe 即将跳转'); }); iframeWindow.addEventListener('pagehide', (event) => { event.preventDefault(); console.log('Iframe 正在隐藏'); }); }); ``` 此方法适用于部分场景,但由于安全策略限制(如跨域),可能无法完全生效[^1]。 --- #### 方法二:重写 `iframe` 的 `window.location` 如果能够访问 `iframe` 的内容(即同源),则可以直接修改其内部的行为,例如覆盖 `location.href` 或其他导航属性。 ```javascript const iframe = document.querySelector('iframe'); iframe.onload = function() { try { const iframeDocument = iframe.contentDocument || iframe.contentWindow.document; const iframeWindow = iframe.contentWindow; // 替换 location.assign 和 location.replace 函数 Object.defineProperty(iframeWindow, 'location', { get: function() { return {}; }, set: function(value) { console.warn('尝试设置新的 URL:', value); throw new Error('禁止更改 iframe 地址'); } }); iframeWindow.history.pushState = function(state, title, url) { console.warn('阻止 pushState 操作:', url); }; iframeWindow.history.replaceState = function(state, title, url) { console.warn('阻止 replaceState 操作:', url); }; } catch (e) { console.error('无法访问 iframe 内容:', e.message); // 可能由于跨域限制引发错误 } }; ``` 上述代码会捕获任何试图改变 `iframe` 当前地址的操作,并抛出异常或记录日志。需要注意的是,这仅在同源的情况下有效[^2]。 --- #### 方法三:使用沙盒模式 (`sandbox`) 属性 HTML 提供了一个名为 `sandbox` 的属性,用于增强 `iframe` 的安全性。启用某些选项后,可以限制 `iframe` 执行脚本、提交表单以及导航至新页面的能力。 ```html <iframe src="example.html" sandbox="allow-scripts"></iframe> ``` 在此配置下,默认禁用了大部分功能(包括导航)。只有显式声明的功能才会被允许。例如,`allow-top-navigation` 将重新启用顶部窗口的导航能力;因此应谨慎选择所需的权限组合[^3]。 --- #### 方法四:动态替换目标链接 假如对 `iframe` 的 HTML 结构有一定掌控权,还可以通过调整超链接的目标属性来避免外部跳转影响父级页面。 ```javascript const iframe = document.querySelector('iframe'); iframe.onload = function() { const links = iframe.contentDocument.querySelectorAll('a[target="_top"], a[target="_parent"]'); links.forEach(link => { link.setAttribute('target', '_self'); // 修改 target 值为 _self link.onclick = function(event) { event.stopPropagation(); // 阻止冒泡 }; }); }; ``` 这种方式适合处理特定类型的锚点标签,但仍然受限于跨域政策的影响[^4]。 --- ### 总结 以上四种方案各有优劣,在实际应用中需综合考虑项目需求和技术约束条件。推荐优先选用 **方法三** (利用 `sandbox` 特性)作为通用的安全防护手段,而对于可控环境下的定制化需求,则可以选择 **方法二** 实现更精细的管控机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值