DOM refresh on long running function

后端 未结 12 2357
醉话见心
醉话见心 2020-11-27 20:54

I have a button which runs a long running function when it\'s clicked. Now, while the function is running, I want to change the button text, but I\'m having problems in some

12条回答
  •  醉酒成梦
    2020-11-27 21:42

    Update: I don't think in the long term that you can be sure of avoiding Firefox's aggressive avoidance of DOM updates without using a timeout. If you want to force a redraw / DOM update, there are tricks available, like adjusting the offset of elements, or doing hide() then show(), etc., but there is nothing very pretty available, and after a while when those tricks get abused and slow down user experience, then browsers get updated to ignore those tricks. See this article and the linked articles beside it for some examples: Force DOM redraw/refresh on Chrome/Mac

    The other answers look like they have the basic elements needed, but I thought it would be worthwhile to mention that my practice is to wrap all interactive DOM-changing functions in a "dispatch" function which handles the necessary pauses needed to get around the fact that Firefox is extremely aggressive in avoiding DOM updates in order to score well on benchmarks (and to be responsive to users while browsing the internet).

    I looked at your JSFiddle and customized a dispatch function the one that many of my programs rely on. I think it is self-explanatory, and you can just paste it into your existing JS Fiddle to see how it works:

    $("#btn").on("click", function() { dispatch(this, dowork, 'working', 'done!'); });
    
    function dispatch(me, work, working, done) {
        /* work function, working message HTML string, done message HTML string */
        /* only designed for a  element */
        var pause = 50, old;
        if (!me || me.tagName.toLowerCase() != 'button' || me.innerHTML == working) return;
        old = me.innerHTML;
        me.innerHTML = working;
        setTimeout(function() {
            work();
            me.innerHTML = done;
            setTimeout(function() { me.innerHTML = old; }, 1500);
        }, pause);
    }
    
    function dowork() {
            for (var i = 1; i<1000000000; i++) {
                //
            }
    
    }
    

    Note: the dispatching function also blocks calls from happening at the same time, because it can seriously confuse users if status updates from multiple clicks are happening together.

提交回复
热议问题