没有jQuery的现代浏览器的width()和height() [英] width() and height() for modern browsers without jQuery

查看:75
本文介绍了没有jQuery的现代浏览器的width()和height()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图为弹性div实现一个简单的fold / unforld效果,即当元素的实际尺寸不是通过CSS设置时,因此不能轻易确定。所以我需要jQuery的width()和height()等价于任意元素;方法应返回可分配给* .style.width / height的内容,以实现折叠/展开效果。这些方法也可以是setter,虽然不一定非常简单(或者不是吗?)

I am trying to implement a simple fold/unforld effect for elastic div's, i.e. when actual dimensions of an element are not set through CSS and thus are not trivially determinable. So I need equivalents of jQuery's width() and height() for arbitrary elements; the methods should return something that would be assignable to *.style.width/height to achieve the fold/unfold effect. The methods can be setters as well, though not necessarily as it's trivial anyway (or is it not?)

兼容性:IE8 +和3个适当的团队:Firefox,Chrome , 苹果浏览器。所以。除了使用jQuery之外没有其他答案,我现在不想做。问题是我不需要支持像IE6 / 7和Netscape这样的古老浏览器。我希望我的代码只是简单的,适用于现代浏览器的首页JavaScript。删除IE8 for IE9也是一种选择。

Compatibility: IE8+ and the adequate gang of 3: Firefox, Chrome, Safari. S.O. doesn't have an answer for this other than "use jQuery" which I don't want to do at the moment. The thing is I don't need to support such archaic browsers as IE6/7 and Netscape. I want my code to be just simple, maiden JavaScript for modern browsers. Dropping IE8 for IE9 is an option, too.

我认为答案可能对许多Web开发人员有用。谢谢!

I think the answer may be useful to many web developers. Thanks!

编辑:我当然理解,分析jQuery(和丢弃过时的怪癖)是一个不错的选择,但我认为有人已经这样做了并且可以与我们分享。

I understand of course, analyzing jQuery (and dropping archaic quirks) is a good option, but I thought someone has done this already and could share with us.

推荐答案

这是我在玩IE8,FF,Chrome和Safari之后今天提出的问题的答案。

Here is an answer to my own question I came up with today after playing with IE8, FF, Chrome and Safari.

假设我们想要垂直折叠和展开div元素(所以我们只谈简单的高度),尽可能少的JavaScript和没有jQuery。可以是要在页面上显示和隐藏的内联错误消息框。消息框本身是弹性的,您不知道它的实际尺寸。这里有两个常见问题需要解决:

Let's say we want to fold and unfold a div element vertically (so we'll be talking only about the height for simplicity) with minimal possible JavaScript and no jQuery. Could be an inline error message box that you want to show and hide nicely on the page. The message box itself is elastic and you don't know its actual dimensions. There are two general problems to be solved here:

问题#1:offsetHeight,clientHeight和scrollHeight属性在浏览器中出了名的不一致。您不能依赖它们,特别是当边距/填充/边框设置为0以外的值并且CSS高度不是默认值时(即实际折叠/展开元素时)。有getComputedStyle(),但只能在理智的浏览器上使用,而不能在IE浏览器中使用。 OTOH,IE的currentStyle属性不会像您预期的那样返回计算值(例如,您可能会将auto视为高度值)。事实证明,没有边距/填充/边框offsetHeight在所有现代浏览器上都是可靠和兼容的。

Problem #1: offsetHeight, clientHeight and scrollHeight properties are notoriously inconsistent across browsers. You can't rely on them especially when margin/padding/border are set to something other than 0 and when the CSS height is something other than default (i.e. when actually folding/unfolding the element). There is getComputedStyle(), but it's available only on sane browsers and not in IE. OTOH, IE's currentStyle property doesn't return computed values as you might expect (e.g. you may see "auto" as the height value). It turns out, with no margin/padding/border offsetHeight is reliable and compatible on all modern browsers.

问题#2:唯一的方法(我知道)到动画你的div元素是改变style.height,但是,它不包括填充和边框,因此你无法将框动画为0或从0开始动画,以获得具有非零填充和边框的元素。 (最重要的是,IE不接受0px作为style.height,所以最小尺寸无论如何都是1px。)

Problem #2: the only way (that I know of) to animate your div element is to change style.height, which, however, doesn't include padding and border, and thus you can't animate the box down to 0 or start your animation from 0 for elements with non-zero padding and border. (On top of that, IE doesn't accept 0px as style.height, so the minimal size would be 1px anyway).

这两个问题的解决方案是换行您的框与另一个具有默认样式的div,即填充/边距/边框都设置为0,这是新div的默认样式。您要折叠和展开的框应该在里面,它不应该有边距设置,如果需要,只有填充和边框。通过这种方式,您将能够(1)通过offsetHeight可靠地确定弹性内盒的高度,以及(2)将外盒的高度设置为1像素和1个像素的动画。

The solution to both problems is to wrap your box around with another div with default style, i.e. padding/margin/border all set to 0, which is the default style for a new div. The box you want to fold and unfold should be inside and it shouldn't have a margin setting, only padding and border if desired. This way, you will be able to (1) reliably determine the height of your elastic inner box via offsetHeight, and (2) animate the height of the outer box to and from 1 pixel.

所以,假设我们要为此设置动画:

So, let's say we want to animate this:

<div id="errmsg" style="display:none">
    <div class="errmsg">
        <div class="window-close" onClick="javascript:showErrMsg('', this.parentNode.parentNode)"></div>
        <div id="errmsg.text"></div>
    </div>
</div>

该框在开头是不可见的。 窗口关闭类是右侧的一个小框,带有十字,用于在单击时隐藏框。使用空字符串调用showErrMsg()会折叠消息框(见下文)。

The box is invisible in the beginning. The "window-close" class is a small box on the right with a cross which is used to hide the box when clicked. Calling showErrMsg() with empty string folds the message box (see below).

我为此错误消息框设置动画的JavaScript代码如下(我也是动画不透明度为简单起见,此处省略):

My JavaScript code to animate this error message box is as follows (I'm also animating opacity which is omitted here for simplicity):

var ANIMATE_STEPS = 10;
var ANIMATE_DELAY = 20;


function _obj(obj, parent)
{
    if (typeof obj == 'string')
        obj = (parent ? parent : document).getElementById(obj);
    return obj;
}

function _setStyleHeight(obj, h)
{
    _obj(obj).style.height = Math.round(h) + 'px';
}

function _animateVertFold(obj, cur, by, lim)
{
    obj = _obj(obj);
    cur += by;
    if (by < 0 && cur <= 1)
    {
        obj.style.display = 'none';
        _setStyleHeight(obj, 1); // IE doesn't accept 0
    }
    else if (by > 0 && cur >= lim)
    {
        _setStyleHeight(obj, lim);
    }
    else
    {
        _setStyleHeight(obj, cur);
        setTimeout('_animateVertFold(\'' + obj.id + '\', ' +
            cur + ', ' + by + ', ' + lim + ')', ANIMATE_DELAY);
    }
}

function _expandElem(obj)
{
    obj = _obj(obj);
    if (obj.style.display == 'none')
    {
        obj.style.overflow = 'hidden';
        _setStyleHeight(obj, 1);
        obj.style.display = 'block';
        var innerDiv = obj.getElementsByTagName('div')[0]; // better way?
        var h = innerDiv.offsetHeight;
        if (h > 0)
            _animateVertFold(obj, obj.offsetHeight, h /  ANIMATE_STEPS, h);
    }
}

function _shrinkElem(obj)
{
    obj = _obj(obj);
    if (!obj.style.display || obj.style.display != 'none')
    {
        obj.style.display = 'block';
        obj.style.overflow = 'hidden';
        var h = obj.offsetHeight;
        _animateVertFold(obj, h, - h /  ANIMATE_STEPS, h);
    }
}


function showErrMsg(msg, id)
{
    id || (id = '_errmsg');
    obj = _obj(id);
    if (msg != '')
    {
        _obj(id + '.text').innerHTML = msg;
        _expandElem(obj);
    }
    else
        _shrinkElem(obj);
}

您可以调用showErrMsg(),代码将负责其余部分。您必须将窗口关闭类定义为模仿GUI关闭窗口按钮的东西。当然,errmsg类作为一个具有不同背景颜色,边框和可能的字体的框。

You can call showErrMsg() and the code will take care of the rest. You will have to define the window-close class as something that mimics a GUI close-window button. And of course the "errmsg" class as a box with distinct background color, border and possibly font face as well.

这篇关于没有jQuery的现代浏览器的width()和height()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆