gpt4 book ai didi

javascript - Tagfield 卷轴不工作

转载 作者:数据小太阳 更新时间:2023-10-29 04:43:30 24 4
gpt4 key购买 nike

我用的是6.0有时我在 ExtJS 6 标记字段中遇到奇怪的问题。我正在使用带有 growMax : 3 的标签字段。现在,当为标记域选择的值超过三个 tyhen 时,我在标记域中得到一个向上和向下的指针选项。

这很好现在奇怪的部分是当我单击向下箭头时,这正好把我带到了字段的底部。我看不到还选择了放在两者之间的其他值。有什么办法可以减慢这些值的滚动速度。

我的 fiddle :Fiddle

重现步骤。

  1. 选择几个值(多于 2 或 3)
  2. 点击向下指针。 (图中红框)Image

它可能会跳过第二个第三个值并引导您结束。

注意:有时我需要对标签字段中的 100 个数据执行此操作。甚至看不到我选择的内容。我也不能改变高度。

是否有任何事件会在单击滚动按钮时触发。

最佳答案

更新(实际实现继承)

好的,看来您确实需要一个基于继承的解决方案。这段代码显然不是惯用的 ExtJS,但它似乎对我有用。首先定义一个自定义的子类SingleLineTag并指定'singleline-tagfield'作为它的xtype(这段代码背后的主要思想有一些描述在“旧答案”部分)

Ext.define('Ext.form.field.SingleLineTag', {
extend: 'Ext.form.field.Tag',
xtype: 'singleline-tagfield',

initEvents: function () {
var me = this;
me.callParent(arguments);

me.itemList.el.dom.parentElement.addEventListener('scroll', Ext.bind(me.zzzOnTagScroll, me));
},

zzzGetTagLastScroll: function () {
var me = this;
return me.zzzLastScroll = me.zzzLastScroll || {
lastIndex: 0,
lastTop: 0,
lastTimeStamp: 0
};
},

zzzScrollToTagIndex: function (index) {
var tagField = this;
var lastScroll = tagField.zzzLastScroll;
if (lastScroll) {
var lstDom = tagField.itemList.el.dom;
var childrenDom = lstDom.children;
var containerDom = tagField.itemList.el.dom.parentElement;

if ((index >= 0) && (index < childrenDom.length)) {
lastScroll.lastIndex = index;
containerDom.scrollTop = lastScroll.lastTop = childrenDom[index].offsetTop - lstDom.offsetTop;
}
}
},

zzzOnTagScroll: function (ev) {
var me = this;
var lastScroll = me.zzzGetTagLastScroll();

// throttle scroll events as thy occur to often and we might scroll to much
if (Math.abs(lastScroll.lastTimeStamp - ev.timeStamp) < 200) {
ev.preventDefault();
return;
}

lastScroll.lastTimeStamp = ev.timeStamp;

var lstDom = me.itemList.el.dom;
var childrenDom = lstDom.children;
var containerDom = me.itemList.el.dom.parentElement;
var scrollTop = containerDom.scrollTop;

var index = lastScroll.lastIndex;
if (index >= childrenDom.length)
index = childrenDom.length - 1;
if (index < 0)
index = 0;
var lstTop = lstDom.offsetTop;
if (scrollTop > lastScroll.lastTop) {
// scrolling down, find next element
for (; index < childrenDom.length; index++) {
if (childrenDom[index].offsetTop - lstTop > scrollTop) {
break;
}
}
if (index < childrenDom.length) {
// we've found the next element so change scroll position to it's top
me.zzzScrollToTagIndex(index);
}
else {
lastScroll.lastIndex = childrenDom.length;
lastScroll.lastTop = containerDom.scrollTop;
}
}
else {
// scrolling up, find prev element
for (; index >= 0; index--) {
if (childrenDom[index].offsetTop - lstTop < scrollTop) {
break;
}
}
if (index >= 0) {
// we've found the prev element so change scroll position to it's top
me.zzzScrollToTagIndex(index);
}
else {
lastScroll.lastIndex = 0;
lastScroll.lastTop = 0;
}
}
},


onBeforeDeselect: function (list, record) {
var me = this;
me.callParent(arguments);
var value = record.get(me.valueField);
var index = me.getValue().indexOf(value);
var lastScroll = me.zzzGetTagLastScroll();
if (lastScroll.lastIndex > index)
lastScroll.lastIndex -= 1;
var nextIndex = (lastScroll.lastIndex > index) ? lastScroll.lastIndex - 1 : lastScroll.lastIndex;
setTimeout(function () {
me.zzzScrollToTagIndex(nextIndex);
}, 0);
},

onItemListClick: function(ev) {
var me = this;

// HACK for IE: throttle click events after scroll
// click on the scrollbar seem to generate click on the "itemList" as well
// which lead to showing of the dropdown
var lastScroll = me.zzzGetTagLastScroll();
if (Math.abs(lastScroll.lastTimeStamp - ev.timeStamp) > 200) {
me.callParent(arguments);
}
}
});

现在更改 items 集合中的 xtype

var shows = Ext.create('Ext.data.Store', {
fields: ['id', 'show'],
data: [
{id: 0, show: 'Battlestar Galactica'},
{id: 11, show: 'Doctor Who'},
{id: 2, show: 'Farscape'},
{id: 3, show: 'Firefly'},
{id: 4, show: 'Star Trek'},
{id: 5, show: 'Star Wars: Christmas Special'}
]
});

Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
title: 'Sci-Fi Television',
height: 200,
width: 300,
items: [{
//xtype: 'tagfield', // old
xtype: 'singleline-tagfield', // new
growMax: 18,
fieldLabel: 'Select a Show',
store: shows,
displayField: 'show',
valueField: 'id',
queryMode: 'local',
filterPickList: true,
}]
});

请注意,如果您不将此元素配置为仅采用单行高度,则它在滚动方面的行为会很奇怪。

请参阅此处的组合代码 Sencha fiddle


旧答案

我不擅长 ExtJS,但我认为一些不太好的答案总比没有答案好。首先,我同意 growMax 以像素为单位,因此 3 太小了。仍在考虑您的问题,似乎没有足够的空间容纳完整的滚动条,因此唯一的方法是添加自定义滚动逻辑。可能最好创建一些继承自 Tag 的新类,但我不确定如何在 ExtJS 中正确地执行此操作,所以这里有一些自定义代码,可能是非惯用代码。

function findComponentByElement(node) {
var topmost = document.body,
target = node,
cmp;

while (target && target.nodeType === 1 && target !== topmost) {
cmp = Ext.getCmp(target.id);

if (cmp) {
return cmp;
}

target = target.parentNode;
}

return null;
}


var getTagLastScroll = function (tagField) {
return tagField.zzzLastScroll = tagField.zzzLastScroll || {
lastIndex: 0,
lastTop: 0,
lastTimeStamp: 0
};
};

var scrollToTagIndex = function (tagField, index) {
var lastScroll = tagField.zzzLastScroll;
if (lastScroll) {
var lstDom = tagField.itemList.el.dom;
var childrenDom = lstDom.children;
var containerDom = tagField.itemList.el.dom.parentElement;

if ((index >= 0) && (index < childrenDom.length)) {
lastScroll.lastIndex = index;
containerDom.scrollTop = lastScroll.lastTop = childrenDom[index].offsetTop - lstDom.offsetTop;

//console.log("Scroll to " + containerDom.scrollTop);
//console.log(lastScroll);

}
}
};

var onTagScroll = function (ev) {
var tagField = findComponentByElement(ev.target);
var lastScroll = getTagLastScroll(tagField);

// need to throttle scroll events or will scroll to much
if (Math.abs(lastScroll.lastTimeStamp - ev.timeStamp) < 200) {
ev.preventDefault();
return;
}

//console.log(ev);
lastScroll.lastTimeStamp = ev.timeStamp;

var lstDom = tagField.itemList.el.dom;
var childrenDom = lstDom.children;
var containerDom = tagField.itemList.el.dom.parentElement;
var scrollTop = containerDom.scrollTop;

//console.log("Before " + containerDom.scrollTop);
//console.log(lastScroll);

var index = lastScroll.lastIndex;
if (index >= childrenDom.length)
index = childrenDom.length - 1;
if (index < 0)
index = 0;
var lstTop = lstDom.offsetTop;
if (scrollTop > lastScroll.lastTop) {
// scrolling down, find next element
for (; index < childrenDom.length; index++) {
if (childrenDom[index].offsetTop - lstTop > scrollTop) {
break;
}
}
if (index < childrenDom.length) {
// we've found the next element so change scroll position to it's top
scrollToTagIndex(tagField, index);
}
else {
lastScroll.lastIndex = childrenDom.length;
lastScroll.lastTop = containerDom.scrollTop;
}
}
else {
// scrolling up, find prev element
for (; index >= 0; index--) {
if (childrenDom[index].offsetTop - lstTop < scrollTop) {
break;
}
}
if (index >= 0) {
// we've found the prev element so change scroll position to it's top
scrollToTagIndex(tagField, index);
}
else {
lastScroll.lastIndex = 0;
lastScroll.lastTop = 0;
}
}
//console.log("After " + containerDom.scrollTop);
//console.log(lastScroll);
};


var beforeDeselect = function (tagField, record) {
var value = record.get(tagField.valueField);
var index = tagField.getValue().indexOf(value);
var lastScroll = getTagLastScroll(tagField);
if (lastScroll.lastIndex > index)
lastScroll.lastIndex -= 1;
var nextIndex = (lastScroll.lastIndex > index) ? lastScroll.lastIndex - 1 : lastScroll.lastIndex;
setTimeout(function () {
scrollToTagIndex(tagField, nextIndex);
}, 0);
};

var attachCustomScroll = function (tagField) {
var containerDom = tagField.itemList.el.dom.parentElement;
containerDom.addEventListener('scroll', onTagScroll);
tagField.on('beforeDeselect', beforeDeselect);
};

你可以通过简单的操作来使用它

var pnl = Ext.create('Ext.form.Panel', { 
...
});
var tagField = pnl.items.items[0];
attachCustomScroll(tagField);

我的代码背后的主要思想是拦截包含 ul 和选定项目的容器元素的滚动事件,而不是将事件视为真正的滚动,而只是将一个元素滚动到它的方向.正常工作所需的数据以唯一的 zzzLastScroll 名称附加回小部件。

还有一些额外的逻辑可以在删除某些项目时使滚动看起来更好。


完整代码(而不是 fiddle )

不幸的是,我没有 ExtJS 帐户,没有它我无法在那里创建一个新的 fiddle ,所以以防万一这里是我用来测试我的代码的修改后的 app.js 的完整代码.

var shows = Ext.create('Ext.data.Store', {
fields: ['id', 'show'],
data: [
{id: 0, show: 'Battlestar Galactica'},
{id: 11, show: 'Doctor Who'},
{id: 2, show: 'Farscape'},
{id: 3, show: 'Firefly'},
{id: 4, show: 'Star Trek'},
{id: 5, show: 'Star Wars: Christmas Special'}
]
});


var pnl = Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
title: 'Sci-Fi Television',
height: 200,
width: 300,
items: [{
xtype: 'tagfield',
growMax: 18,
fieldLabel: 'Select a Show',
store: shows,
displayField: 'show',
valueField: 'id',
queryMode: 'local',
filterPickList: true,


}]
});

window.tagField = pnl.items.items[0];
window.lstDom = window.tagField.itemList.el.dom;
window.container = window.lstDom.parentElement;

tagField.setValue([11, 3, 4, 5]);

function findComponentByElement(node) {
var topmost = document.body,
target = node,
cmp;

while (target && target.nodeType === 1 && target !== topmost) {
cmp = Ext.getCmp(target.id);

if (cmp) {
return cmp;
}

target = target.parentNode;
}

return null;
}


var getTagLastScroll = function (tagField) {
return tagField.zzzLastScroll = tagField.zzzLastScroll || {
lastIndex: 0,
lastTop: 0,
lastTimeStamp: 0
};
};

var scrollToTagIndex = function (tagField, index) {
var lastScroll = tagField.zzzLastScroll;
if (lastScroll) {
var lstDom = tagField.itemList.el.dom;
var childrenDom = lstDom.children;
var containerDom = tagField.itemList.el.dom.parentElement;

if ((index >= 0) && (index < childrenDom.length)) {
lastScroll.lastIndex = index;
containerDom.scrollTop = lastScroll.lastTop = childrenDom[index].offsetTop - lstDom.offsetTop;

//console.log("Scroll to " + containerDom.scrollTop);
//console.log(lastScroll);

}
}
};

var onTagScroll = function (ev) {
var tagField = findComponentByElement(ev.target);
var lastScroll = getTagLastScroll(tagField);

if (Math.abs(lastScroll.lastTimeStamp - ev.timeStamp) < 200) {
ev.preventDefault();
return;
}

//console.log(ev);
lastScroll.lastTimeStamp = ev.timeStamp;

var lstDom = tagField.itemList.el.dom;
var childrenDom = lstDom.children;
var containerDom = tagField.itemList.el.dom.parentElement;
var scrollTop = containerDom.scrollTop;

//console.log("Before " + containerDom.scrollTop);
//console.log(lastScroll);

var index = lastScroll.lastIndex;
if (index >= childrenDom.length)
index = childrenDom.length - 1;
if (index < 0)
index = 0;
var lstTop = lstDom.offsetTop;
if (scrollTop > lastScroll.lastTop) {
// scrolling down, find next element
for (; index < childrenDom.length; index++) {
if (childrenDom[index].offsetTop - lstTop > scrollTop) {
break;
}
}
if (index < childrenDom.length) {
// we've found the next element so change scroll position to it's top
scrollToTagIndex(tagField, index);
}
else {
lastScroll.lastIndex = childrenDom.length;
lastScroll.lastTop = containerDom.scrollTop;
}
}
else {
// scrolling up, find prev element
for (; index >= 0; index--) {
if (childrenDom[index].offsetTop - lstTop < scrollTop) {
break;
}
}
if (index >= 0) {
// we've found the prev element so change scroll position to it's top
scrollToTagIndex(tagField, index);
}
else {
lastScroll.lastIndex = 0;
lastScroll.lastTop = 0;
}
}
//console.log("After " + containerDom.scrollTop);
//console.log(lastScroll);
};


var beforeDeselect = function (tagField, record) {
var value = record.get(tagField.valueField);
var index = tagField.getValue().indexOf(value);
var lastScroll = getTagLastScroll(tagField);
if (lastScroll.lastIndex > index)
lastScroll.lastIndex -= 1;
var nextIndex = (lastScroll.lastIndex > index) ? lastScroll.lastIndex - 1 : lastScroll.lastIndex;
setTimeout(function () {
scrollToTagIndex(tagField, nextIndex);
}, 0);
};

var attachCustomScroll = function (tagField) {
var containerDom = tagField.itemList.el.dom.parentElement;
containerDom.addEventListener('scroll', onTagScroll);
tagField.on('beforeDeselect', beforeDeselect);
};

attachCustomScroll(window.tagField);

关于javascript - Tagfield 卷轴不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42897876/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com