extjs7 classic自定义滚动条导致内容宽度异常

版本

extjs 7.4.0 classic

原因

ext框架会根据浏览器全局滚动条尺寸自动修改内容的style属性以适配宽度,所以局部滚动条样式如果与全局样式不同,会导致异常。

解决

设置全局滚动条尺寸

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

源码

  • ext-core/src/layout/ContextItem.js
//修改组件属性
 writeProps: function(dirtyProps, flushing) {
...
    var me = this,
        el = me.el,
        target = me.target,
        styleInfo = me.styleInfo,
        styles = {},
        width = dirtyProps.width,
        height = dirtyProps.height,
        styleCount = 0, // used as a boolean, the exact count doesn't matter
        info, propName, numericValue, hasWidth, hasHeight, isAbsolute, scrollbarSize,
        style, targetEl, scroller;
...
    // 当设置宽高且存在滚动条时根据滚动条尺寸调整宽高
    if (me.wrapsComponent && Ext.isIE9) {
        // when we set a width and we have a vertical scrollbar (overflowY), we need
        // to add the scrollbar width... conversely for the height and overflowX
        if ((hasWidth = width !== undefined && me.hasOverflowY) ||
            (hasHeight = height !== undefined && me.hasOverflowX)) {
            // check that the component is absolute positioned.
            isAbsolute = me.isAbsolute;

            if (isAbsolute === undefined) {
                isAbsolute = false;
                targetEl = me.target.getTargetEl();
                style = targetEl.getStyle('position');
                me.isAbsolute = isAbsolute = (style === 'absolute'); // cache it
            }

            if (isAbsolute) {
            	// 此处获取全局滚动条尺寸
                scrollbarSize = Ext.scrollbar.size();

                if (hasWidth) {
                    width = parseInt(width, 10) + scrollbarSize.width;
                    styles.width = width + 'px';
                    ++styleCount;
                }

                if (hasHeight) {
                    height = parseInt(height, 10) + scrollbarSize.height;
                    styles.height = height + 'px';
                    ++styleCount;
                }
            }
        }
    }

    // we make only one call to setStyle to allow it to optimize itself:
    if (styleCount) {
        el.setStyle(styles);
    }
},
  • ext-core/src/dom/Element.js
/**
 * Wrapper for setting style properties, also takes single object parameter of
 * multiple styles.
 *
 * Styles should be a valid DOM element style property.
 * [Valid style property names](http://www.w3schools.com/jsref/dom_obj_style.asp)
 * (_along with the supported CSS version for each_)
 *
 *     // <div id="my-el">Phineas Flynn</div>
 *
 *     var el = Ext.get('my-el');
 *
 *     // two-param syntax
 *     el.setStyle('color', 'white');
 *
 *     // single-param syntax
 *     el.setStyle({
 *         fontWeight: 'bold',
 *         backgroundColor: 'gray',
 *         padding: '10px'
 *     });
 *
 * @param {String/Object} prop The style property to be set, or an object of
 * multiple styles.
 * @param {String} [value] The value to apply to the given property, or null if
 * an object was passed.
 * @return {Ext.dom.Element} this
 */
setStyle: function(prop, value) {
    var me = this,
        dom = me.dom,
        hooks = me.styleHooks,
        style = dom.style,
        name = prop,
        hook;

    // we don't promote the 2-arg form to object-form to avoid the overhead...
    if (typeof name === 'string') {
        hook = hooks[name];

        if (!hook) {
            hooks[name] = hook = { name: Element.normalize(name) };
        }

        value = (value == null) ? '' : value; // map null && undefined to ''

        if (hook.set) {
            hook.set(dom, value, me);
        }
        else {
            style[hook.name] = value;
        }

        if (hook.afterSet) {
            hook.afterSet(dom, value, me);
        }
    }
    else {
        for (name in prop) {
            hook = hooks[name];

            if (!hook) {
                hooks[name] = hook = { name: Element.normalize(name) };
            }

            value = prop[name];
            value = (value == null) ? '' : value; // map null && undefined to ''

            if (hook.set) {
                hook.set(dom, value, me);
            }
            else {
                style[hook.name] = value;
            }

            if (hook.afterSet) {
                hook.afterSet(dom, value, me);
            }
        }
    }

    return me;
},

posted on 2022-04-11 22:38  路过君  阅读(3)  评论(0编辑  收藏  举报

导航