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;
},