js监听某个元素高度变化来改变父级iframe的高度
最近需要做一个iframe调用其他页面内容,这个iframe地址是可变化的,但是里面的内容高度不确定且里面内容高度可调整,所以需要通过监听iframe里面body的高度变化来调整iframe的高度。
后面发现了一个好用的插件detect-element-resize.js,首先看一下这个插件的介绍:
插件简介
跨浏览器,基于事件,元素调整大小检测。
简而言之,此实现不使用内部计时器来检测大小更改(就像我发现的大多数实现一样)。它使用scroll大多数浏览器上的onresize事件,以及IE10及以下的事件。
使用的方法不仅检测javascript生成的调整大小更改,还检测CSS伪类的更改,例如:hover,CSS动画等。
插件兼容性
Chrome
Firefox
IE 11 及以下 (在11,10,9,8和7上测试)
已知问题
在IE 10及更低版本上:如果分离元素并重新附加它,则需要再次添加调整大小侦听器。
源代码
(function () {
var attachEvent = document.attachEvent,
stylesCreated = false; if (!attachEvent) {
var requestFrame = (function(){
var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
function(fn){ return window.setTimeout(fn, 20); };
return function(fn){ return raf(fn); };
})(); var cancelFrame = (function(){
var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
window.clearTimeout;
return function(id){ return cancel(id); };
})(); function resetTriggers(element){
var triggers = element.__resizeTriggers__,
expand = triggers.firstElementChild,
contract = triggers.lastElementChild,
expandChild = expand.firstElementChild;
contract.scrollLeft = contract.scrollWidth;
contract.scrollTop = contract.scrollHeight;
expandChild.style.width = expand.offsetWidth + 1 + 'px';
expandChild.style.height = expand.offsetHeight + 1 + 'px';
expand.scrollLeft = expand.scrollWidth;
expand.scrollTop = expand.scrollHeight;
}; function checkTriggers(element){
return element.offsetWidth != element.__resizeLast__.width ||
element.offsetHeight != element.__resizeLast__.height;
} function scrollListener(e){
var element = this;
resetTriggers(this);
if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
this.__resizeRAF__ = requestFrame(function(){
if (checkTriggers(element)) {
element.__resizeLast__.width = element.offsetWidth;
element.__resizeLast__.height = element.offsetHeight;
element.__resizeListeners__.forEach(function(fn){
fn.call(element, e);
});
}
});
}; /* Detect CSS Animations support to detect element display/re-attach */
var animation = false,
animationstring = 'animation',
keyframeprefix = '',
animationstartevent = 'animationstart',
domPrefixes = 'Webkit Moz O ms'.split(' '),
startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
pfx = '';
{
var elm = document.createElement('fakeelement');
if( elm.style.animationName !== undefined ) { animation = true; } if( animation === false ) {
for( var i = 0; i < domPrefixes.length; i++ ) {
if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
pfx = domPrefixes[ i ];
animationstring = pfx + 'Animation';
keyframeprefix = '-' + pfx.toLowerCase() + '-';
animationstartevent = startEvents[ i ];
animation = true;
break;
}
}
}
} var animationName = 'resizeanim';
var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
} function createStyles() {
if (!stylesCreated) {
//opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
var css = (animationKeyframes ? animationKeyframes : '') +
'.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
'.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style'); style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
} head.appendChild(style);
stylesCreated = true;
}
} window.addResizeListener = function(element, fn){
if (attachEvent) element.attachEvent('onresize', fn);
else {
if (!element.__resizeTriggers__) {
if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
createStyles();
element.__resizeLast__ = {};
element.__resizeListeners__ = [];
(element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
'<div class="contract-trigger"></div>';
element.appendChild(element.__resizeTriggers__);
resetTriggers(element);
element.addEventListener('scroll', scrollListener, true); /* Listen for a css animation to detect element display/re-attach */
animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
if(e.animationName == animationName)
resetTriggers(element);
});
}
element.__resizeListeners__.push(fn);
}
}; window.removeResizeListener = function(element, fn){
if (attachEvent) element.detachEvent('onresize', fn);
else {
element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
if (!element.__resizeListeners__.length) {
element.removeEventListener('scroll', scrollListener);
element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
}
}
}
})();
调用方法
addResizeListener(element,fun) //element为监听的元素,fun为当有变化时触发的方法 //例如监听body的高度变化:
addResizeListener(document.getElementsByTagName("body")[0],detectCallback);
var detectCallback = function() {
console.log('页面body高度发生了变化')
};
实例:
监听iframe页面变化时iframe的高度等于iframe里面页面body的高度
<iframe src="url" frameborder="0" id="container"></iframe> //iframe 页面代码
window.onload=function(){
setParentIframeHeight('container');
addResizeListener(document.getElementsByTagName("body")[0], detectCallback);
} var detectCallback = function() {
setParentIframeHeight('container');
}; function setParentIframeHeight(id){
var parentIframe = parent.document.getElementById(id);
parentIframe.height = document.body.scrollHeight;
}
detect-element-resize.js插件地址:https://github.com/sdecima/javascript-detect-element-resize
js监听某个元素高度变化来改变父级iframe的高度的更多相关文章
- js监听dom元素内容变化
$("#divid").bind('DOMNodeInserted', function(e) { alert('element now contains: ' + $(e.tar ...
- js监听文本框内容变化
js监听文本框内容变化 原理很简单,就是在外部先声明一个用来记录input值的变量,然后每0.1秒比较这个值与input的值,如果发生改变,则运行自己的代码,同时改变变量.从而实现对input值改变的 ...
- js监听文本框值变化事件,就oninput & onpropertychange & onkeyup & onchange的区别
在Web前端项目中实时监听文本框的值变化是非常常见的功能,通常最简单最容易想到的是onkeyup和onchange事件,但是在使用onkeyup来监听键盘事件的时候,监听不到鼠标右键的粘贴.复制的操作 ...
- js监听input输入字符变化
<p class="text-input"> <input type="text" id="username" autoC ...
- js监听指定元素的css动画属性
MDN 监听css动画,开始,迭代次数,结束,中断 回调函数返回 animationEvent属性 <!DOCTYPE html> <html> <head> &l ...
- js监听textarea 内容的变化,并计算内容的长度c
html代码如下: <div class="customer-message"> <label for="customerMessage&quo ...
- js监听url的hash变化和获取hash值
当浏览器浏览器的url进行变化时,浏览器默认是会去服务器将相应的资源给请求下来的,在不阻止默认行为的前提下,使用给url加锚点的方式(hash模式),让浏览器不跳转. window.addEventL ...
- js -- 监听窗口的大小变化
- 【链接】js监听input输入框内容变化
https://blog.csdn.net/idomyway/article/details/79078625 $("#input1").bind("input prop ...
随机推荐
- 判断一个数是否为回文数(js)
//判断是否为回文数:若n=1234321,则称n为一回文数 let readline = require("readline-sync"); let newNum = 0; co ...
- 解决GitHub下载资源慢的问题
打开 C:\Windows\System32\drivers\etc\hosts 添加 # GitHub 解决下载速度慢的问题 192.30.253.113 github.com 151.101.18 ...
- MacBook Pro实现共享屏幕(多台mac之间)
1 开启允许所有用户控制屏幕 设置— 共享 2 在另一台MacBook Pro里打开finder窗口,并设置好network显示边栏 3 另一台机器发送请求控制 找 ...
- 【转】bitbake 笔记
原文 http://blog.csdn.net/xiaofeng_yan/article/details/6757725 1 当你已经编完一个系统比如sato映像,在编一个meta-toolchain ...
- JS笔记02
回顾: html: 超文本标记语言 后缀名: *.html 或 *.htm 标签分类: 围堵标签: 双标签 <html>标签体</html> 空标签: 单标签 <br/& ...
- 【网络协议】动态主机配置协议DHCP
动态主机配置协议DHCP 当某组织获得一块地址后,就可以为本组织内的主机或者路由器分配IP地址.这个分配工作可以由系统管理员手动通过网络管理工具来完成.也可以由动态主机配置协议(Dynamic Hos ...
- BZOJ 1015 并查集&连通块
很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道互相直接或 ...
- PAM安全认证模块
- BZOJ1601 [Usaco2008 Oct]灌水[最小生成树]
显然分析可知这个图最后连起来是一个森林,每棵树有一个根再算一个代价.那么这些跟需要连向某一点一个建立水库的代价,且根可以有多个但不能没有,则考虑用超级源点0向所有点连虚边,Prim跑MST即可保证有至 ...
- luogu1261 服务器储存信息问题[最短路]
首先$O(n^2\log n)$暴力很好想,直接每个点出发跑一遍最短路,排$dis$统计一下即可.考虑怎么优化.发现$rank$很小,考虑从$rank$入手.换一种统计方法,看每个点$x$如果作为别的 ...