Visual Studio 突出显示onresize
了我的标签属性div
,并说它不是 HTML5 的有效属性。这是真的?我应该改用什么?会是这种情况似乎有点愚蠢。
6 回答
Microsoft 的 Internet Explorer 支持onresize
所有 HTML 元素。在所有其他浏览器中,onresize
仅在window
对象上可用。
https://developer.mozilla.org/en-US/docs/Web/API/Window.onresize
如果您想div
在所有浏览器中使用 onresize,请检查:
http://marcj.github.io/css-element-queries/
该库有一个ResizeSensor
可用于resize
检测的类。
将以下 CSS 和 JavaScript 添加到您的页面,并使用addResizeListener
和removeResizeListener
方法来监听元素大小的变化(有关详细信息的博客文章:http ://www.backalleycoder.com/2013/03/18/cross-browser-event-基于元素调整大小检测/):
调整传感器 CSS
.resize-triggers {
visibility: hidden;
}
.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%;
}
调整事件方法
以下是启用调整大小事件侦听所需的 JavaScript。前两个函数是在主要 addResizeListener 和 removeResizeListener 方法中使用的先决条件。
(function(){
var attachEvent = document.attachEvent;
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);
});
}
});
};
}
window.addResizeListener = function(element, fn){
if (attachEvent) element.attachEvent('resize', fn);
else {
if (!element.__resizeTriggers__) {
if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
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);
}
element.__resizeListeners__.push(fn);
}
};
window.removeResizeListener = function(element, fn){
if (attachEvent) element.detachEvent('resize', fn);
else {
element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
if (!element.__resizeListeners__.length) {
element.removeEventListener('scroll', scrollListener);
element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
}
}
}
})();
Demo-licious!
这是该方法的伪代码用法。
var myElement = document.getElementById('my_element'),
myResizeFn = function(){
/* do something on resize */
};
addResizeListener(myElement, myResizeFn);
removeResizeListener(myElement, myResizeFn);
仅存Window.onResize
在于规范中。请记住,每个IFrame
元素都会创建Window
支持onResize
. 因此,IMO 检测元素大小变化的最可靠方法是将隐藏的 iframe 附加到元素。
如果您对简洁便携的解决方案感兴趣,请查看此插件。只需 1 行代码即可侦听更改 div 的宽度或高度的事件。
<!-- (1) include plugin script in a page -->
<script src="/src/jquery-element-onresize.js"></script>
// (2) use the detectResizing plugin to monitor changes to the element's size:
$monitoredElement.detectResizing({ onResize: monitoredElement_onResize });
// (3) write a function to react on changes:
function monitoredElement_onResize() {
// logic here...
}
我们现在有ResizeObserver,今天(2021-01-21)浏览器支持率为 89.6%。
还有适用于旧浏览器的 polyfill,比如juggle/resize-observer
目前所有主流浏览器都不支持 html-element 的 resize 事件,只支持 window 对象。
您可以做的是拦截用户交互以构建您自己的侦听器,如下所示:
function detectResize(_element)
{
let promise = {};
let _listener = [];
promise.addResizeListener = function(listener)
{
if(typeof(listener) != "function") { return; }
if(_listener.includes(listener)) { return; };
_listener.push(listener);
};
promise.removeResizeListener = function(listener)
{
let index = _listener.indexOf(listener);
if(index >= 0) { _listener.splice(index, 1); }
};
let _size = { width: _element.clientWidth, height: _element.clientHeight };
function checkDimensionChanged()
{
let _currentSize = { width: _element.clientWidth, height: _element.clientHeight };
if(_currentSize.width != _size.width || _currentSize.height != _size.height)
{
let previousSize = _size;
_size = _currentSize;
let diff = { width: _size.width - previousSize.width, height: _size.height - previousSize.height };
fire({ width: _size.width, height: _size.height, previousWidth: previousSize.width, previousHeight: previousSize.height, _element: _element, diff: diff });
}
_size = _currentSize;
}
function fire(info)
{
if(!_element.parentNode) { return; }
_listener.forEach(listener => { listener(info); });
}
let mouseDownListener = event =>
{
let mouseUpListener = event =>
{
window.removeEventListener("mouseup", mouseUpListener);
window.removeEventListener("mousemove", mouseMoveListener);
};
let mouseMoveListener = event =>
{
checkDimensionChanged();
};
window.addEventListener("mouseup", mouseUpListener);
window.addEventListener("mousemove", mouseMoveListener);
};
_element.addEventListener("mousedown", mouseDownListener);
window.addEventListener("resize", event =>
{
checkDimensionChanged();
});
return promise;
}
如何使用它:
document.addEventListener("DOMContentLoaded", event =>
{
let textarea = document.querySelector("textarea");
let detector = detectResize(textarea);
let listener = info => { console.log("new width: ", info.width, " new height: ", info.height); };
detector.addResizeListener(listener);
});
html:
<textarea></textarea>
CSS:
html, body
{
height: 100%;
box-sizing: border-box;
overflow: hidden;
margin: 0px;
}
textarea
{
resize: both;
width: 96px;
height: 112px;
width: 100%;
height: 100%;
border: 1px solid black;
}
一个纯粹而简单的 JavaScript 实现。
.resizable {
resize: both;
overflow: auto;
width: 200px;
border: 1px solid black;
padding: 20px;
margin-bottom: 120px;
}
<div class='resizable' onresize="this.innerText = this.w + ',' + this.h" onmousemove="if ((this.w && this.w !== this.offsetWidth) || (this.h && this.h !== this.offsetHeight)) { eval(this.getAttribute('onresize')) } this.w = this.offsetWidth; this.h = this.offsetHeight;">
test
</div>