Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

onIdle (Александр Михалицын)
Author Message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 83
   поощрить/наказать


PostPosted: Thu Aug 20, 2009 6:01 am (написано за 1 минуту 19 секунд)
   Post subject: onIdle
Reply with quote

Выношу из темы forum.dklab.ru/viewtopic.php?t=34195.

Вот, 2 реализации -- от меня и от топикстартера (K.Wiolowan):
Code (JavaScript): скопировать код в буфер обмена
/*

var idleManager = new function()
{
        var self = this;

        var lag, repeat, param, func, timeout_id, func_busy, param_busy; //private properties

        /**
         * This method set event in object.
         * @access private
         */

        var set_event = function(event_type, event_interpriter, object)
        {
                if ((event_type == 'load' || event_type == 'keydown') && object == window)
                {
                        object = object.document.documentElement;
                }

                if (object.addEventListener)
                {
                        object.addEventListener(event_type, event_interpriter, false);
                } else {
                        object.attachEvent('on' + event_type, event_interpriter);
                }
        }

        /**
         * This method unset event in object.
         * @access private
         */

        var unset_event = function(event_type, event_interpriter, object)
        {
                if ((event_type == 'load' || event_type == 'keydown') && object == window)
                {
                        object = object.document.documentElement;
                }

                if (object.removeEventListener)
                {
                        object.removeEventListener(event_type, event_interpriter, false);
                } else {
                        object.detachEvent('on' + event_type, event_interpriter);
                }
        }

        var idleWrapper = function()
        {
                if (timeout_id)
                {
                        clearTimeout(timeout_id);
                        func_busy.apply(window, param_busy);
                }

                timeout_id = setTimeout(function()
                {
                        if (func.apply(window, param) !== false)
                        {
                                idleManager.id = setTimeout(arguments.callee, repeat);
                        } else {
                                self.stop();
                        }
                }, lag);
        }

        self.stop = function()
        {
                clearTimeout(timeout_id);

                unset_event('load', idleWrapper, window);
                unset_event('keydown', idleWrapper, document);
                unset_event('mousemove', idleWrapper, document);
                unset_event('mousedown', idleWrapper, document);
        }

        self.start = function(_func, _param, _func_busy, _param_busy, _lag, _repeat)
        {
                lag = _lag || 500;
                repeat = _repeat || 100;
                param = _param || [];
                func = _func || function() {};
                func_busy = _func_busy || function() {};
                param_busy = _param_busy || [];

                set_event('load', idleWrapper, window);
                set_event('keydown', idleWrapper, document);
                set_event('mousemove', idleWrapper, document);
                set_event('mousedown', idleWrapper, document);

                idleWrapper();
        }
}

//
var on_not_busy = function(param1, param2)
{
        document.getElementById('output').innerHTML = ' !    : ' + param1 + ':' + param2;
}

var on_busy = function(param1, param2)
{
        document.getElementById('output').innerHTML = ' !    : ' + param1 + ':' + param2;
}

idleManager.start(on_not_busy, ['  =)', '   =))'], on_busy, ['  =)', '   =))'], 1000, 200);
Code (JavaScript): скопировать код в буфер обмена
idleManager = new function(){
        var id=null
        var func_idle= null
        var func_busy= null
        var func_stop= null
        var lag=500
        var repeat=100
        var param={}
        this.idleWrapper= function(){
                return function(){
                        if (id){
                                clearTimeout(id);
                                if(func_busy) func_busy.apply(window, [param]);
                        }
                        id = setTimeout(function(){
                                if(func_idle.apply(window, [param])){
                                        id = setTimeout(arguments.callee, repeat)
                                }else{
                                         stopIdle()
                                        if(func_stop) func_stop.apply(window, [param]);
                                }
                                }, lag);
                }
        }
        this.start= function(_func_idle, _param, _lag, _repeat, _func_busy, _func_stop ) {
                func_idle= _func_idle
                param= _param || {}
                func_busy= _func_busy || null
                func_stop= _func_stop || null
                lag= _lag || 500
                repeat= _repeat || 100
                window.onload = this.idleWrapper()
                document.onkeydown = this.idleWrapper()
                document.onmousemove = this.idleWrapper()
                document.onmousedown = this.idleWrapper()
                this.idleWrapper()()
        }
        var stopIdle= function(){
                clearTimeout(id)
                document.onkeydown = document.onmousemove = document.onmousedown = null
        }
        this.stop = stopIdle
}

function idleProcess(param){
                for (var i = 0; i < 100000; i++) param.s+=i*0.000127;
                document.getElementById('output').innerHTML = 'Idling ' + (param.count++) +
                'th time; counted sum=' + Math.floor(param.s) +
                '<br />Waiting for the sum to be &gt; 50000000<br /> Move your mouse or start typing..'+
                '<br />Doubleclick to stop idle process';
                return param.s < 50000000 ? true : false;
}
idleManager.start(
        idleProcess,
        {count:0, s:0},
        1000,
        200,
        function(){
                document.getElementById('output').innerHTML = 'Busy with a user..';
        },
        function(){
                document.getElementById('output').innerHTML = 'I\'m thru....';
        }
);
document.ondblclick=function(){
        idleManager.stop()
        document.getElementById('output').innerHTML = 'Idle process stopped<br />'+
        'Doubleclick to start again'
        document.ondblclick=function(){
                idleManager.start(idleProcess,         {count:0, s:0})
        }
}


Last edited by Александр Михалицын on Thu Jun 23, 2011 1:23 pm; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Thu Aug 20, 2009 10:56 am (спустя 4 часа 54 минуты; написано за 11 минут 7 секунд)
   Post subject:
Reply with quote

Назначение и смысл названия переменных lag, repeat? Может быть стоит ограничиться одним lag, имя которому timeout?
от использования функций unset_event и set_event можно отказаться. Так как фактически они используются только в start/stop.
Очень сомнительное условие в самом начале этих функций - этому условию соответствует только set_event('load', idleWrapper, window); соответственно, если есть необходимость передавайте сразу требуемое значение.
Плохо, что idleManager - и внешнее и внутреннее определения. Внутренний переименовать бы. Или внешний.
Не уловил необходимости двух вложенных setTimeout.
кто останавливает таймер idleManager.id?
Так ли необходимо передавать параметры функциям func и func_busy? Может ограничиться просто вызовом соответствующего callback?

Постоянные моргания при зажатой клавише клавиатуры и движении мышью.
Но зажатый CAPSLOCK (то есть нажал и держу) говорит, что ресурсы не заняты, хотя при одноразовом нажатии (нажал/отпустил) видно, что страница выходит из спячки.
Нет изменений при зажатой клавише мыши (то есть нажал и держу) - при одноразовом нажатии/отпускании реакция есть.

Опциональное замечание - некоторые синонимы
busy, active
not busy, idle, inactive, passive

Резюме: еще работать и работать.
Back to top
View user's profile Send private message
Александр Михалицын
Модератор



Joined: 23 May 2008
Posts: 1299
Карма: 83
   поощрить/наказать


PostPosted: Thu Aug 20, 2009 11:59 am (спустя 1 час 2 минуты; написано за 1 минуту 29 секунд)
   Post subject:
Reply with quote

Rumata,
согласен. А почему ты не комментировал когда это было еще тут (forum.dklab.ru/viewtopic.php?t=34195)? (-:
К сожалению, участник K.Wiolowan, редко заходит... Ну да ладно, потом исправлю все недочеты. Что касается функций set/unset_event, ага, кривоваты чуток. (-:
Back to top
View user's profile Send private message Send e-mail
K.Wiolowan
Участник форума



Joined: 22 Feb 2006
Posts: 53
Карма: 11
   поощрить/наказать


PostPosted: Thu Aug 20, 2009 12:12 pm (спустя 13 минут; написано за 18 минут 22 секунды)
   Post subject:
Reply with quote

Rumata wrote:
Назначение и смысл названия переменных lag, repeat? Может быть стоит ограничиться одним lag, имя которому timeout?
lag - это начальная задержка между последним действием пользователя и активизацией idle-задачи, default= 500 ms
repeat - это интервал между завершением (порции) idle-задачи, и новой idle-задачей, в течение которого у пользователя есть возможность перехватить управление на себя. default = 100 ms.
Необходимо так выставлять lag, repeat, а тж. квантировать idle-задачу, чтобы не нервировать пользователя "заморозкой" браузера. В качестве примера "тупой" комбинации:
lag=repeat=100 ms, продолжительность кванта idle-задачи - 10 сек.

ИМХО, чем более ресурсоемка фоновая задача, тем бОльший лаг должен определяться в onIdle.

В идеале, конечно, хорошо бы фоновые задачи определять через worker threads, но это под силу пока только Firefox 3.5, Chrome и сайтам с установленным Google Gears
Back to top
View user's profile Send private message
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Aug 20, 2009 5:49 pm (спустя 5 часов 36 минут; написано за )
   Post subject:
Reply with quote

Вообще, если больше одного сайта будет активно использовать эту технику, и несколько этих сайтов могут быть открыты у пользователя одновременно, то пользователь может прийти в бешенство из-за постоянных «подвисаний» браузера (ведь он-то может работать еще с каким-то другим сайтом).

Так что, ИМХО, если вы хотите писать аналог BOINC в браузере, то будьте добры использовать неблокирующий javascript, ибо в противном случае пользователи могут начать жаловаться на впш сайт. В любом случае, реализация хотя бы с worker threads должна быть (а не «может быть будет», как сейчас), для корректной работы бедного браузера.
Back to top
View user's profile Send private message Send e-mail
K.Wiolowan
Участник форума



Joined: 22 Feb 2006
Posts: 53
Карма: 11
   поощрить/наказать


PostPosted: Fri Sep 18, 2009 1:52 pm (спустя 28 дней 20 часов 3 минуты; написано за 21 секунду)
   Post subject:
Reply with quote

jQuery idleTimer plugin (paulirish.com/demo/idle-timer?comment=)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML