firefox上使用js模拟text-overflow:ellipsis效果的快速实现

firefox下使用js模拟text-overflow:ellipsis效果的快速实现
/**
     * 计算textOverflow样式需要选择的字符
     * @private
     *
     * @param {Element} el Element对象
     * @param {Number} width 容器宽度
     * @param {Boolean} ellipsis 是否一定要出现省略号
     */
    _count: function (el, width, ellipsis) {
        /* 计算cache的名称 */
        var o = E.get(el), fontWeight = o.fontWeight, cacheName =
                'font-family:' + o.fontFamily + ';font-size:' + o.fontSize
                + ';word-spacing:' + o.wordSpacing + ';font-weight:' + (fontWeight.number() == 401 ? 700 : fontWeight)
                + ';font-style:' + o.fontStyle + ';font-variant:' + o.fontVariant,
            cache = E.Cache[cacheName];

        if (!cache) {
            o = E.appendTo(E._eEmpty, el);

            E.set(o, 'float:left;' + cacheName);
            cache = E.Cache[cacheName] = [];

            /* 计算ASCII字符的宽度cache */
            for (i = 0; i < 256; i++) {
                i == 32 ? (o.innerHTML = '&nbsp;') : E.setText(o, String.fromCharCode(i));
                cache[i] = o.offsetWidth;
            }

            /* 计算非ASCII字符的宽度、字符间距、省略号的宽度 */
            E.setText(o, '一');
            cache[256] = o.offsetWidth;
            E.setText(o, '一一');
            cache[257] = o.offsetWidth - cache[256] * 2;
            cache[258] = cache['.'.charCodeAt(0)] * 3 + cache[257] * 3;

            E.set(o, '');
            o.innerHTML = '';
            E.appendTo(o);
        }

        for (
            /* wordWidth是每个字符或子节点计算之前的宽度序列 */
            var node = el.firstChild, charWidth = cache[256], wordSpacing = cache[257], ellipsisWidth = cache[258],
                wordWidth = [], ellipsis = ellipsis ? ellipsisWidth : 0;
            node;
            node = node.nextSibling
        ) {
            if (width < ellipsis) {
                E.appendTo(node);
            }
            else if (node.nodeType == 3) {
                for (var i = 0, text = node.nodeValue, length = text.length; i < length; i++) {
                    o = text.charCodeAt(i);
                    /* 计算增加字符后剩余的长度 */
                    wordWidth.push([width, node, i]);
                    width -= (i ? wordSpacing : 0) + (o < 256 ? cache[o] : charWidth);
                    if (width < ellipsis) {
                        break;
                    }
                }
            }
            else {
                o = node.tagName;
                if (o == 'IMG' || o == 'TABLE') {
                    /* 特殊元素直接删除 */
                    o = node;
                    node = node.previousSibling;
                    E.appendTo(o);
                }
                else {
                    wordWidth.push([width, node]);
                    width -= node.offsetWidth;
                }
            }
        }

        if (width < ellipsis) {
            /* 过滤直到能得到大于省略号宽度的位置 */
            while (o = wordWidth.pop()) {
                width = o[0];
                node = o[1];
                o = o[2];
                if (node.nodeType == 3) {
                    if (width >= ellipsisWidth) {
                        node.nodeValue = node.nodeValue.substring(0, o) + '...';
                        return true;
                    }
                    else if (!o) {
                        E.appendTo(node);
                    }
                }
                else if (E._count(node, width, true)) {
                    return true;
                }
                else {
                    E.appendTo(node);
                }
            }

            /* 能显示的宽度小于省略号的宽度,直接不显示 */
            el.innerHTML = '';
        }
    }