欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Chorme下iframe请求多次的解决办法&SimpleModal的chorme bug

程序员文章站 2022-04-27 14:45:10
...

     Chorme下iframe加载会出现两次大家有没有遇到过这种情况?在我的项目中就遇到这种问题了,所以我想把我的解决办法说一下以让大家不用在这个上面费时间,我的问题是在用JQuery插件SimpleModal的时候发现的,会加载两次html请求,后来一步一步调试加查看一下资料,iframe的onload会在chorme下调用两次,下面是一个小demo可以让你查看出来;

 

<html>
<head></head>
    <body><div id="msg">状态:</div></body>  
    <script>  
    var msg = document.getElementById("msg");  
    var iframe = document.createElement("iframe");  
    iframe.onload = function(){ msg.innerHTML += "onload,"; }
    document.body.appendChild(iframe);   
    iframe.src = "http://www.baidu.com"  ;
    </script>  
</html>

 

    请把这段代码放在chorme下和firefox下分别运行,会发现chorme下会调用两次onload方法,原因是:你是先把iframe append在body上,此时iframe调用了一次onload,但src是空的当然不会发生什么事情,然后给src赋值又调了一次,然后baidu被加载进来。怎么解决呢?知道了这个原理之后其实就很容易了,我们把赋值src放到append之前就好了,保证让iframe加在body之前给src赋值,如下:

 

 

<html>
<head></head>
    <body><div id="msg">状态:</div></body>  
    <script>  
    var msg = document.getElementById("msg");  
    var iframe = document.createElement("iframe");  
    iframe.onload = function(){ msg.innerHTML += "onload,"; }
    iframe.src = "http://www.baidu.com"  ;
    document.body.appendChild(iframe);   
    </script>  
</html>

    JQuery的弹框插件SimpleModal也有这个问题,用过这个插件的同学们不知道有没有发现chorme下会读到两次请求呢?其实问题就在于它的一段代码如下:

 

 

			// create the overlay
			s.d.overlay = $('<div></div>')
				.attr('id', s.o.overlayId)
				.addClass('simplemodal-overlay')
				.css($.extend(s.o.overlayCss, {
					display: 'none',
					opacity: s.o.opacity / 100,
					height: s.o.modal ? w[0] : 0,
					width: s.o.modal ? w[1] : 0,
					position: 'fixed',
					left: 0,
					top: 0,
					zIndex: s.o.zIndex + 1
				}))
				.appendTo(s.o.appendTo);

			// create the container
			s.d.container = $('<div></div>')
				.attr('id', s.o.containerId)
				.addClass('simplemodal-container')
				.css($.extend(s.o.containerCss, {
					display: 'none',
					position: 'fixed',
					zIndex: s.o.zIndex + 2
				}))
				.append(s.o.close && s.o.closeHTML
					? $(s.o.closeHTML).addClass(s.o.closeClass)
					: '')
				.appendTo(s.o.appendTo);

			s.d.wrap = $('<div></div>')
				.attr('tabIndex', -1)
				.addClass('simplemodal-wrap')
				.css({height: '100%', outline: 0, width: '100%'})
				.appendTo(s.d.container);

			// add styling and attributes to the data
			// append to body to get correct dimensions, then move to wrap
			s.d.data = data
				.attr('id', data.attr('id') || s.o.dataId)
				.addClass('simplemodal-data')
				.css($.extend(s.o.dataCss, {
						display: 'none'
				})).appendTo('body');
				
			
			data = null;

			s.setContainerDimensions();
			s.d.data.appendTo(s.d.wrap);

  

   请看最后两句,先是把s.d.data放在Body里,然后调用setContainerDimensions计算完位置后,又重新append到wrap上,这样两次append导致了请求了两次,javascript运行很快的,所以chomre下出现第一次请求还未完成就取消了,又重新请求的,这样在工程里会出现很多问题,那么解决方法就用上述demo的原理,改完如下:

 

 

 

			// create the overlay
			s.d.overlay = $('<div></div>')
				.attr('id', s.o.overlayId)
				.addClass('simplemodal-overlay')
				.css($.extend(s.o.overlayCss, {
					display: 'none',
					opacity: s.o.opacity / 100,
					height: s.o.modal ? w[0] : 0,
					width: s.o.modal ? w[1] : 0,
					position: 'fixed',
					left: 0,
					top: 0,
					zIndex: s.o.zIndex + 1
				}))
				.appendTo(s.o.appendTo);

			// create the container
			s.d.container = $('<div></div>')
				.attr('id', s.o.containerId)
				.addClass('simplemodal-container')
				.css($.extend(s.o.containerCss, {
					display: 'none',
					position: 'fixed',
					zIndex: s.o.zIndex + 2
				}))
				.append(s.o.close && s.o.closeHTML
					? $(s.o.closeHTML).addClass(s.o.closeClass)
					: '')
				.appendTo(s.o.appendTo);

			s.d.wrap = $('<div></div>')
				.attr('tabIndex', -1)
				.addClass('simplemodal-wrap')
				.css({height: '100%', outline: 0, width: '100%'})
				.appendTo(s.d.container);

			// add styling and attributes to the data
			// append to body to get correct dimensions, then move to wrap
			s.d.data = data
				.attr('id', data.attr('id') || s.o.dataId)
				.addClass('simplemodal-data')
				.css($.extend(s.o.dataCss, {
						display: 'none'
				}));
				
			var tempSrc = data.find("iframe").attr("src");
			data.find("iframe").removeAttr("src");
			s.d.data.appendTo('body');
			
			data = null;

			s.setContainerDimensions();
			s.d.data.appendTo(s.d.wrap);
			s.d.data.find("iframe").attr("src",tempSrc);

   

    我们先把src拿出来,这样append的时候就会是空的,就不会重复请求src中的url,等都append完后再把src换给他,解决!