执行单击 + 拖动鼠标操作时 Internet Explorer 冻结。如何检测这种情况的原因?

Posted

技术标签:

【中文标题】执行单击 + 拖动鼠标操作时 Internet Explorer 冻结。如何检测这种情况的原因?【英文标题】:Internet Explorer freezes when a click + drag mouse action is performed. How to detect the cause of this? 【发布时间】:2011-10-18 12:12:43 【问题描述】:

我正在开发一个用于创建简单图表的 javascript 应用程序,但在 Internet Explorer(第 8 版)中存在一些性能问题。

该应用程序可用于在图表上画线(见图)。画线有两个主要的处理程序。 ONMOUSEUP 事件获取用户的点击,这表明用户想要在线上放置一个点并开始一个新的线段(线由多个线段组成)。

ONMOUSEMOVE 处理程序在用户绘制线条时绘制一个淡出的片段作为视觉帮助。

请参考这些图片以获取画线过程的屏幕截图: http://imgur.com/TuueR http://i51.tinypic.com/fxjqf.jpg

如果用户单击鼠标 (mousedown) 但没有释放它,而是开始拖动鼠标,IE 将完全冻结。一段时间后,它会解冻并照常进行。

另一方面,Chrome 可以很好地处理这个问题(当拖动操作发生时,MOUSEMOVE 处理程序会工作,并且只有在 ONMOUSEUP 事件触发后才会放置点。

我的理论是 Explorer 可能是单线程的,在这种情况下他会选择 MOUSEMOVE 事件,但仅在 ONMOUSEUP 事件完成后才执行它们(这意味着在拖动操作期间基本上什么都不做),但是我不知道如何检查这是不是真的,或者如何解决它。

我已经使用 IE8 内置的 JS 分析器进行了一些分析,并且这两个处理程序都被调用了通常的次数,没有任何函数被调用数千次会导致冻结。分析器在 IE 被冻结时被冻结,并且在解冻之前不输出任何内容,之后结果似乎与没有冻结操作相同。

编辑:这里是根据 dynaTrace 分析器工具的时间线:http://i51.tinypic.com/348sxty.jpg。

【问题讨论】:

您是否在普通的 html 元素中创建图表和褪色线? @Esailija 是的,它们主要是跨度元素。点具有背景图像,而线条是具有顶部或右侧边框的透明元素。 【参考方案1】:

问题在于更新 DOM 是一项非常昂贵的操作。现在,如果没有限制,mousemove 事件会不断触发,如果您在每个触发的 mousemove 事件上更新 DOM,旧浏览器就无法跟上。

解决方案可能将 mousemove 事件限制至少 200 毫秒。这意味着您只会在鼠标停止移动 200 毫秒后更新 DOM,从而给浏览器一些时间来恢复。

这就是限制 mousemove 事件的方式:

jQuery( "#element").bind( "mousemove", function()
//Code to react to mousemove goes here
//Also add code here to check if the position has actually changed from last time,
//So you don't update the DOM for nothing
.throttle( 200 ) );

节流方法所需的代码:

Function.prototype.throttle = function( delay ) 
var timeridto = 0, callback = this;

    function r()
    var     args = Array.prototype.slice.call( arguments ),
        self = this;
        clearTimeout( timeridto );
        timeridto = setTimeout( function()callback.apply( self, args ); , delay );
    ;

    r.cancel = function()
     clearTimeout( timeridto );   
    

    return r;
;

如果这不能解决问题,那么您可以使用html5 canvas 或(IE 为excanvas)进行绘图操作。

【讨论】:

我已经在这里做了一些性能优化,强制只在网格上绘制线条(如图所示)。这样我只在鼠标在 x 或 y 轴上移动了至少 10px 时才更新 DOM。当用户正常画线时,IE中没有性能问题。通常我的意思是 CLICK_MOUSE(创建一个点)、MOVE_MOUSE(从该方向的起点绘制一条线)、CLICK、MOVE、CLICK、MOVE.. 等等。这个用例在每个浏览器中都可以正常工作。 但是,在 IE 中绘制线条时的 MOUSEDOWN + MOUSEMOVE 组合会完全冻结浏览器。所以,总而言之: MOUSEDOWN + MOUSEUP = CLICK -> MOUSEMOVE -> CLICK -> MOVE 工作正常。 MOUSEDOWN + MOUSEMOVE(点击未完成)=冻结问题 你有我可以看到的页面吗?或者你能发个jsfiddle吗? 不,很抱歉,我的 NDA 阻止我将它放到网上。 我无法从您的帖子中真正看出拖动时发生了哪些操作,以及在没有拖动的情况下使用 mousemove 进行了哪些操作。辅助淡出线是否仅在拖动时绘制,是否也进行了优化?

以上是关于执行单击 + 拖动鼠标操作时 Internet Explorer 冻结。如何检测这种情况的原因?的主要内容,如果未能解决你的问题,请参考以下文章

电脑应用拖到上边放大

ImageIcon 在窗口中单击并拖动

当父元素可拖动时如何允许文本框插入符号位置(在鼠标单击时)

jQuery Draggable - 通过单击开始拖动元素,无需按住鼠标

在opengl中,如何将鼠标跟随更改为鼠标单击、拖动和释放?

PyQtgraph - 通过鼠标单击和拖动绘制 ROI