【发布时间】:2013-08-07 13:18:47
【问题描述】:
这是我在这里的第一个问题,我不是英语母语人士,所以如果这让我的解释难以理解,我提前道歉。
上下文
我负责开发一个操作词汇集的小型应用程序。 该应用程序建立在 GWT 之上,由 GWT-Bootstrap 和其他一些库添加,与应用程序的 ui 部分无关。 为了向用户展示这个词汇的术语,我使用了一个树结构,从视觉上讲。
故事
树的要求很少,它必须允许其项目的拖放功能并显示它们之间的连接器。
我从使用原生 GWT 组件中的 Tree ui 类开始。事实证明,在树中加载了很多术语后,即使在生产模式下,性能也会下降。
我决定尝试 CellTree 实现,但它不适合我,因为让“showmore”按钮消失并不是一件容易的事,而且树的样式也是如此。
我终于从头开始实现了我自己的树实现。 这个实现本质上依赖于一个简单的 html 列表结构(ul-li),并且最大程度地受益于 css 功能。实际上,扩展树节点是通过 css 完成的,使用了一种称为“checkbox hack”的技巧。
此时树的自定义实现速度很快(比树或单元树更好),甚至填充了数千个项目,并且满足要求,但是...
问题
当一个项目被拖到其他项目上时,这些项目的样式会根据放置的可能性而改变。
第一种解决方案
第一个想法是利用 css,并使用 :hover 选择器来更改项目的样式,具体取决于它们的类。 但是在当前的浏览器(特别是 Chrome)中存在一个主要问题,如果鼠标左键按下,则不会触发 css :hover,当您拖动某些东西时就是这种情况(铬问题 122746)
似乎我不得不忘记一个专属的 css 解决方案,直到 :hover 触发问题将被关闭。
第二个解决方案
我得到的唯一其他解决方案是以编程方式更改项目的样式。
处理程序的代码
@Override
public void onDragEnter(DragEnterEvent event)
{
if (event.getSource() instanceof Word)
{
event.stopPropagation();
event.preventDefault();
Word word = (Word) event.getSource();
word.addStyleDependentName("over");
}
}
@Override
public void onDragLeave(DragLeaveEvent event)
{
if (event.getSource() instanceof Word)
{
event.stopPropagation();
event.preventDefault();
Word word = (Word) event.getSource();
word.removeStyleDependentName("over");
}
}
它适用于一些项目,但在处理数千个项目时,它会使应用程序冻结,并且呈现在某种程度上是随机的。
精度
在处理树中的 5000 个项目时出现问题(应用程序必须处理此类数据集)。
我知道有效的事件处理问题,例如事件冒泡,并且处理程序是唯一的,因为当潜在处理程序的数量(如果针对每个项目特定)是作为数量缺乏性能的因素时,建议使用它项目增加。
第二次我用测速仪分析了问题的根源,结果我不明白:
事件在树的顶部元素上非常慢,特别是在样式重新计算后需要 1 秒才能触发的绘制事件 Slow events Speed Tracer Screenshot
事件速度在树的底部元素上是公平的 Fair enougth speed events Speed Tracer Screenshot
问题
几天以来我一直被这个问题困扰,我想知道是否有人能指出我所缺少的。 也许,这种行为是完全正常的,但也许有解决此类问题的方法? 如果有人能在这一点上帮助我,我会很高兴。
感谢您的回复!
lilBrain
【问题讨论】:
-
+1 格式精美
-
你找到解决办法了吗?你有其他地方的示例代码吗?
标签: performance events gwt drag-and-drop tree