Pergunta

I use Paul Irish's jquery idle timer and fancyapps' fancybox on one of my sites. I would like to make the idle timer to detect fancybox's slideshow being played (space bar pressed) as activity until it's stopped and thus keep the session active. Basically I need to make sure that when someone watches the slideshow of a lot of pictures, it doesn't stop at the end of the timer I set for inactivity.

I know client side scripting is not secure to manage sessions (I've been through that with several other posts), so that is not the point of my question here; I'm fully aware of the security backfalls which I'm planning to manage in a different way (ie. logout if js is not activated in the browser).

the relevant code is (I believe):

fancybox:

$.extend(F, {
    ...
    defaults: {
        ...
        keys  : {
            ...
            play   : [32], // space - start/stop slideshow
                            ...
        }
        ...
        }
...
// Manage slideshow:
    //   $.fancybox.play(); - toggle slideshow
    //   $.fancybox.play( true ); - start
    //   $.fancybox.play( false ); - stop
    play: function ( action ) {
        var clear = function () {
                clearTimeout(F.player.timer);
            },
            set = function () {
                clear();

                if (F.current && F.player.isActive) {
                    F.player.timer = setTimeout(F.next, F.current.playSpeed);
                }
            },
            stop = function () {
                clear();

                $('body').unbind('.player');

                F.player.isActive = false;

                F.trigger('onPlayEnd');
            },
            start = function () {
                if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
                    F.player.isActive = true;

                    $('body').bind({
                        'afterShow.player onUpdate.player'   : set,
                        'onCancel.player beforeClose.player' : stop,
                        'beforeLoad.player' : clear
                    });

                    set();

                    F.trigger('onPlayStart');
                }
            };

        if (action === true || (!F.player.isActive && action !== false)) {
            start();
        } else {
            stop();
        }
    }
...
}

idle timer:

( function( $ ) {

$.idleTimer = function( firstParam, elem, opts ) {

    // defaults that are to be stored as instance props on the elem
    opts = $.extend( {
        startImmediately: true,   //starts a timeout as soon as the timer is set up
        idle: false,              //indicates if the user is idle
        enabled: true,            //indicates if the idle timer is enabled
        timeout: 30000,           //the amount of time (ms) before the user is considered idle
        events: "mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove" // activity is one of these events
    }, opts );


    elem = elem || document;

    var jqElem = $( elem ),
        obj = jqElem.data("idleTimerObj") || {},

        /* (intentionally not documented)
         * Toggles the idle state and fires an appropriate event.
         * @return {void}
         */
        toggleIdleState = function( myelem ) {

            // curse you, mozilla setTimeout lateness bug!
            if ( typeof myelem === "number" ) {
                myelem = undefined;
            }

            var obj = $.data( myelem || elem, "idleTimerObj" );

            //toggle the state
            obj.idle = !obj.idle;

            // reset timeout
            var elapsed = ( +new Date() ) - obj.olddate;
            obj.olddate = +new Date();

            // handle Chrome always triggering idle after js alert or comfirm popup
            if ( obj.idle && ( elapsed < opts.timeout ) ) {
                obj.idle = false;
                clearTimeout( $.idleTimer.tId );
                if ( opts.enabled ) {
                    $.idleTimer.tId = setTimeout( toggleIdleState, opts.timeout );
                }
                return;
            }

            // create a custom event, but first, store the new state on the element
            // and then append that string to a namespace
            var event = $.Event( $.data( elem, "idleTimer", obj.idle ? "idle" : "active" ) + ".idleTimer" );
            $( elem ).trigger( event );
        },

        /**
         * Stops the idle timer. This removes appropriate event handlers
         * and cancels any pending timeouts.
         * @return {void}
         * @method stop
         * @static
         */
        stop = function( jqElem ) {

            var obj = jqElem.data("idleTimerObj") || {};

            //set to disabled
            obj.enabled = false;

            //clear any pending timeouts
            clearTimeout( obj.tId );

            //detach the event handlers
            jqElem.off(".idleTimer");
        };

    obj.olddate = obj.olddate || +new Date();

    if ( typeof firstParam === "number" ) {
        opts.timeout = firstParam;
    } else if ( firstParam === "destroy" ) {
        stop( jqElem );
        return this;
    } else if ( firstParam === "getElapsedTime" ) {
        return ( +new Date() ) - obj.olddate;
    }


    /* (intentionally not documented)
     * Handles a user event indicating that the user isn't idle.
     * @param {Event} event A DOM2-normalized event object.
     * @return {void}
     */
    jqElem.on( $.trim( ( opts.events + " " ).split(" ").join(".idleTimer ") ), function() {
        var obj = $.data( this, "idleTimerObj" );

        //clear any existing timeout
        clearTimeout( obj.tId );

        //if the idle timer is enabled
        if ( obj.enabled ){
            //if it's idle, that means the user is no longer idle
            if ( obj.idle ){
                toggleIdleState( this );
            }

            //set a new timeout
            obj.tId = setTimeout( toggleIdleState, obj.timeout );
        }
    });

    obj.idle = opts.idle;
    obj.enabled = opts.enabled;
    obj.timeout = opts.timeout;

    //set a timeout to toggle state. May wish to omit this in some situations
    if ( opts.startImmediately ) {
        obj.tId = setTimeout( toggleIdleState, obj.timeout );
    }

    // assume the user is active for the first x seconds.
    jqElem.data( "idleTimer", "active" );

    // store our instance on the object
    jqElem.data( "idleTimerObj", obj );
};

$.fn.idleTimer = function( firstParam, opts ) {
    // Allow omission of opts for backward compatibility
    if ( !opts ) {
        opts = {};
    }

    if ( this[0] ){
        $.idleTimer( firstParam, this[0], opts );
    }

    return this;
};

})( jQuery );

EDITED (Solved using JFK's suggestion - waiting for his response)

This is the final code I used that solved my issue (just don't want to take JFK's credit for it):

<script type="text/javascript">
//<![CDATA[

    var Timer;
    var TotalSeconds;
    var timethis;

    function CreateTimer(TimerID, Time) {
        Timer = document.getElementById(TimerID);
        TotalSeconds = Time;

        UpdateTimer()
        timethis = window.setTimeout("Tick()", 1000);
    }

    function Tick() {
        if (TotalSeconds <= 1) {
            window.location.href = '<?php echo wp_logout_url(); ?>';
        }

        TotalSeconds -= 1;
        UpdateTimer()
        timethis = window.setTimeout("Tick()", 1000);
    }

    function UpdateTimer() {
        var Seconds = TotalSeconds;

        var Minutes = Math.floor(Seconds / 60);
        Seconds -= Minutes * (60);


        var TimeStr = Minutes + ":" + LeadingZero(Seconds)


        Timer.innerHTML = TimeStr;
    }       

    function LeadingZero(Time) {

        return (Time < 10) ? "0" + Time : + Time;

    }

    function TimeThis() {
        var hheight = $(window).height();
        $( "#timepop" ).dialog({
            resizable: false,
            closeOnEscape: true,
            height:150,
            modal: true,
            buttons: {
              "Continue": function() {
                  window.clearTimeout(timethis);
                  $( this ).dialog( "close" );
              },
              "Logout": function() {
                  window.location.href = '<?php echo wp_logout_url(); ?>';
              }
            }
        })
    };

    (function($){

    var timeinmin = 40, // Time in mins before dialog box opens
        countdown = 5, // Time in mins until dialog box remains open
        timeout = timeinmin*60*1000,
        countdial = countdown*60;

    $.idleTimer(timeout);

    $(document).bind("idle.idleTimer", function(){
        parent.jQuery.fancybox.close();
        CreateTimer("countd", countdial);
        TimeThis();
    });

    $(document).ready(function() {
        $(".fancybox").fancybox();
    });

    $(function(){
    $(".fancybox")
        .attr('rel', 'gallery')
        .fancybox({
            autoPlay: false,
            playSpeed: 3000,
            beforeShow: function () {
                $.fancybox.wrap.bind("contextmenu", function (e) {
                        return false; 
                });
            },
            helpers : {
                overlay : {
                    css : {
                        'background' : 'rgba(0, 0, 0, 0.9)'
                    }
                }
            },
            padding : 0,
            onPlayStart: function () {
                $.idleTimer("destroy");
            },
            onPlayEnd: function () {
                $.idleTimer(timeout);
                $(document).bind("idle.idleTimer", function(){
                    parent.jQuery.fancybox.close();
                    CreateTimer("countd", countdial);
                    TimeThis();
                });
            },
        });
    });

    })(jQuery);

    $("img.lazy").lazyload({ 
        effect : "fadeIn",
        threshold : 200
    });//]]> 
</script>
Foi útil?

Solução

You could use onPlayStart and onPlayEnd fancybox callbacks to perform your own functions, something like :

$(".fancybox").fancybox({
    // API options and callbacks
    onPlayStart: function(){
        // myTimerPause()
    },
    onPlayEnd: function(){
        // myTimerStart()
    }
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top