JavaScript'te boşta kalma süresini zarif bir şekilde nasıl tespit edebilirim?


478

JavaScript'te " boşta " zamanı tespit etmek mümkün mü ?
Birincil kullanım durumum muhtemelen içeriği önceden getirmek veya önceden yüklemek olacaktır.

Boşta kalma süresi: Kullanıcının kullanılmadığı veya CPU kullanmadığı süre


7
BOŞALTMA ZAMANI'nı nasıl tanımlarsınız?
Itay Moav -Malimovka


74
Buradaki cevapların neredeyse% 50'si saf Javascript için bu kadar basit bir görev için jQuery kullanmıştır. Özellikle OP'nin Javascript'i istediği gibi, bu daralmanın ötesinde. Çilekli dondurma isteyin, bunun yerine yarı müstakil bir ahır alın.
TheCarver

4
Senin için StackOverflow
robertmain

5
@TheCarver - Bu kadar basit bir şey için bir jQuery kütüphanesi kurmak gerçekten çok saçma ve renderleme süresini uzatıyor ve enerji kullanımını artırıyor. İnsanlar biraz daha aşağı kaydırmalı. Vanilya Javascript'te de neredeyse kopyala yapıştır çözümü vardır.
Frank Conijn

Yanıtlar:


437

Mousemove ve keypress olaylarını işleyen JQuery kullanan basit bir komut dosyası. Süre dolarsa sayfa yeniden yüklenir.

<script type="text/javascript">
var idleTime = 0;
$(document).ready(function () {
    //Increment the idle time counter every minute.
    var idleInterval = setInterval(timerIncrement, 60000); // 1 minute

    //Zero the idle timer on mouse movement.
    $(this).mousemove(function (e) {
        idleTime = 0;
    });
    $(this).keypress(function (e) {
        idleTime = 0;
    });
});

function timerIncrement() {
    idleTime = idleTime + 1;
    if (idleTime > 19) { // 20 minutes
        window.location.reload();
    }
}
</script>   

16
$ (Document) .ready (function () gövdesinden sonra noktalı virgül eksik. Ayrıca setInterval çağrısında, işlev adının etrafındaki tırnak işaretleri ile çalışmaz ve bundan sonra parantez gerekmez. Sadece: setInterval (timerIncrement, 60000)
Jesse Roper

9
@Jesse: Önerileriniz iyi, kod böyle olmalı. Ama sadece bu değişiklikler olmadan bile, kodun tamamen işlevsel olduğunu belirtmek istedim. Bir ifade ifadesinin sonundaki noktalı virgüller isteğe bağlıdır ve aslında bir dize iletebilirsiniz setInterval; bu daha sonra JavaScript olarak değerlendirilir.
Felix Kling

6
Sadece idleTime++;yerine kullanabilirsinizidleTime = idleTime + 1;
Mike Causer

7
Bu bir kullanıcının sisteminde ağır değil mi? Diyelim ki, ağır bir bilgisayarda değil, oldukça eski bir tarayıcıya sahip bir kullanıcı, yarım gün için bir javascript uygulamasında çalışıyor ve kullanıcı her faresini hareket ettirdiğinde bu işlevleri işliyor ... Acaba bu kazandı mı? kullanıcının deneyimini etkilemez ...
Sander

5
@PietBinnenbocht Ayrıca, bu gibi şeyleri optimize etmeye başlarsanız, dize işlemlerinden daha hızlı oldukları için 'mousemove keydown click'bit bayraklarını ( Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK) kullanmak gibi dizeleri alan her işlevi de değiştirebilirsiniz . Ama bunu gerçekten yapmak istiyor musun?
Killah

361

JQuery kullanmadan, yalnızca vanilya JavaScript'i:

var inactivityTime = function () {
    var time;
    window.onload = resetTimer;
    // DOM Events
    document.onmousemove = resetTimer;
    document.onkeypress = resetTimer;

    function logout() {
        alert("You are now logged out.")
        //location.href = 'logout.html'
    }

    function resetTimer() {
        clearTimeout(time);
        time = setTimeout(logout, 3000)
        // 1000 milliseconds = 1 second
    }
};

Ve ihtiyacınız olan işlevi başlatın (örneğin: onPageLoad).

window.onload = function() {
  inactivityTime(); 
}

Gerekirse daha fazla DOM etkinliği ekleyebilirsiniz. En çok kullanılanlar:

document.onload = resetTimer;
document.onmousemove = resetTimer;
document.onmousedown = resetTimer; // touchscreen presses
document.ontouchstart = resetTimer;
document.onclick = resetTimer;     // touchpad clicks
document.onkeypress = resetTimer;
document.addEventListener('scroll', resetTimer, true); // improved; see comments

Veya bir dizi kullanarak istediğiniz olayları kaydedin

window.addEventListener('load', resetTimer, true);
var events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
events.forEach(function(name) {
 document.addEventListener(name, resetTimer, true); 
});

DOM Etkinlikleri listesi: http://www.w3schools.com/jsref/dom_obj_event.asp

Unutmayın window, veya documentihtiyaçlarınıza göre. Burada aralarındaki farkları görebilirsiniz: Javascript'te pencere, ekran ve belge arasındaki fark nedir?

Kod @ frank-conijn ve @daxchen ile güncellendi : window.onscrollkaydırma kaydırılabilir bir öğenin içindeyse kaymaz , çünkü kaydırma olayları kabarcıklanmaz. window.addEventListener('scroll', resetTimer, true)üçüncü argüman dinleyiciye yakalama aşamasında kabarcık aşaması yerine olayı yakalamasını söyler.


58
Sade javascript yaklaşımını çok daha iyi seviyorum.
Manatax

4
bir zamanlayıcıyı kesinlikle sıfırlamak, zamanlayıcının kendisi (yüksek hassasiyetli) sayacı OLABİLİR olduğunda, başka bir şeyin tamsayı sayımını tutmak için zaman aşımını yapmaktan daha doğrudan / sezgisel ve doğru bir yaklaşımdır.
Josh Sutterfield

2
@mpsbhat sadece bir console.log veya uyarı ekleyip çalışmadığına bakın. Veya bu etkinlikleri document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
kaydedin

2
Evet ... Çalışıyorum. jsfiddle.net/mpsbhat/6b6mja5t/1 . Teşekkürler @equiman
mpsbhat

6
Bir bayrak var notidle sahip olmak çok daha iyi olurdu; yalnızca olaylarda flag = true olarak ayarlayın. Daha sonra resetTimer fonksiyonunda notidle bayrağının doğru olup olmadığını test edin, zamanlayıcı sıfırlanırsa veya oturumu kapatın. Bu, zamanlayıcıyı sürekli sıfırlamanın karmaşıklık yükünü ortadan kaldıracaktır.
MartinWebb

75

Equiman'ın cevabını geliştirmek:

function idleLogout() {
    var t;
    window.onload = resetTimer;
    window.onmousemove = resetTimer;
    window.onmousedown = resetTimer;  // catches touchscreen presses as well      
    window.ontouchstart = resetTimer; // catches touchscreen swipes as well 
    window.onclick = resetTimer;      // catches touchpad clicks as well
    window.onkeypress = resetTimer;   
    window.addEventListener('scroll', resetTimer, true); // improved; see comments

    function yourFunction() {
        // your function for too long inactivity goes here
        // e.g. window.location.href = 'logout.php';
    }

    function resetTimer() {
        clearTimeout(t);
        t = setTimeout(yourFunction, 10000);  // time is in milliseconds
    }
}
idleLogout();

.
Dışında faaliyet tespiti ile ilgili gelişmeler ve gelen değişimden documentiçinwindow , bu komut dosyası aslında tarafından boşta yerine izin vermek yerine, işlevini çağırır.

Sıfır CPU kullanımını doğrudan yakalamaz, ancak bu mümkün değildir, çünkü bir işlevi yürütmek CPU kullanımına neden olur. Ve kullanıcı hareketsizliği sonunda sıfır CPU kullanımına yol açar, dolaylı olarak sıfır CPU kullanımını yakalar.


3
window.onscrollKaydırma kaydırılabilir bir öğenin içindeyse ateşlenmeyeceğini belirtmek istedim , çünkü kaydırma olayları kabarmaz. Kullanarak window.addEventListener('scroll', resetTimer, true), üçüncü argüman dinleyiciye faz (IE> 8) captureyerine bubblefaz sırasında olay yakalamasını söyler, bu cevaba bakınız
DaxChen

@DaxChen - document.onscrollKaydırma kaydırılabilir bir çocuğun içindeyse aynı sorunu yaşamıyor musunuz?
Frank Conijn

2
Evet, söylediğim nokta kullanmak addEventListeneryerine kullanmaktır onscroll.
DaxChen

@DaxChen - Tamam, bunu kastederek bunun için çalışıp çalışmadığınızı merak ediyordum, ama şimdi açık. Cevabı buna göre düzenledim. Yorum için teşekkürler.
Frank Conijn

Cevabımı bu önemli bilgilerle güncelleyeceğim, diğer kopyaları heveslendirip hatamı yapıştırmak için. @DaxChen ve Frank
equiman

33

Bir yıl önce bunu yapan küçük bir lib yarattım:

https://github.com/shawnmclean/Idle.js

Açıklama:

Kullanıcının tarayıcıdaki etkinliğini bildirmek için küçük javascript kütüphanesi (uzakta, boşta, web sayfasına bakmamak, farklı bir sekmede vb.). jquery gibi herhangi bir javascript kütüphanesinden bağımsızdır.

Visual Studio kullanıcıları bunu NuGet'ten alabilir: PM> Install-Package Idle.js


32

İşte tvanfosson'un fikrinin kaba bir jQuery uygulaması:

$(document).ready(function(){

   idleTime = 0;

   //Increment the idle time counter every second.
   var idleInterval = setInterval(timerIncrement, 1000);

   function timerIncrement()
   {
     idleTime++;
     if (idleTime > 2)
     {
       doPreload();
     }
   }

   //Zero the idle timer on mouse movement.
   $(this).mousemove(function(e){
      idleTime = 0;
   });

   function doPreload()
   {
     //Preload images, etc.
   }

})

9
Bu çözüm klavye olaylarını dikkate almaz.
Daniel Silveira

7
Asla setIntervalbir ip geçirmeyin ! Değişken olarak bir işlev verin!
Eric

1
Bu aslında çalışmaz, çünkü setInterval()genel kapsamdaki ifadeyi değerlendirmek için bir dize iletilir ve böylece timerIncrement().ready işleyici işlevinin içindeki işlevi bulamaz . Bu ASLA dizeleri ASLA geçirmemek için başka bir nedendir setInterval(). Sadece gerçek bir fonksiyon referansını iletin ve bu problemi yaşamayacaksınız çünkü mevcut kapsamda değerlendiriliyorlar.
jfriend00

Teşekkürler, setInterval için ASLA dizeleri geçirme gereğinin farkında değildim. Cevabım güncellendi.
Peter J

24

Yukarıdaki Iconic çözümüne benzer (jQuery özel etkinliği ile) ...

// use jquery-idle-detect.js script below
$(window).on('idle:start', function(){
  //start your prefetch etc here...
});

$(window).on('idle:stop', function(){
  //stop your prefetch etc here...
});

//jquery-idle-detect.js
(function($,$w){
  // expose configuration option
  // idle is triggered when no events for 2 seconds
  $.idleTimeout = 2000;

  // currently in idle state
  var idle = false;

  // handle to idle timer for detection
  var idleTimer = null;

  //start idle timer and bind events on load (not dom-ready)
  $w.on('load', function(){
    startIdleTimer();
    $w.on('focus resize mousemove keyup', startIdleTimer)
      .on('blur',idleStart) //force idle when in a different tab/window
      ;
  ]);

  function startIdleTimer() {
    clearTimeout(idleTimer); //clear prior timer

    if (idle) $w.trigger('idle:stop'); //if idle, send stop event
    idle = false; //not idle

    var timeout = ~~$.idleTimeout; // option to integer
    if (timeout <= 100) timeout = 100; // min 100ms
    if (timeout > 300000) timeout = 300000; // max 5 minutes

    idleTimer = setTimeout(idleStart, timeout); //new timer
  }

  function idleStart() {
    if (!idle) $w.trigger('idle:start');
    idle = true;
  }

}(window.jQuery, window.jQuery(window)))

20

Alt çizgi ve jquery ile daha zarif yapabilirsiniz -

$('body').on("click mousemove keyup", _.debounce(function(){
    // do preload here
}, 1200000)) // 20 minutes debounce

16

Cevabım vijay'ın cevabından ilham aldı , ancak yardımcı olabileceği herkes için paylaşacağımı düşündüğüm daha kısa, daha genel bir çözüm.

(function () { 
    var minutes = true; // change to false if you'd rather use seconds
    var interval = minutes ? 60000 : 1000; 
    var IDLE_TIMEOUT = 3; // 3 minutes in this example
    var idleCounter = 0;

    document.onmousemove = document.onkeypress = function () {
        idleCounter = 0;
    };

    window.setInterval(function () {
        if (++idleCounter >= IDLE_TIMEOUT) {
            window.location.reload(); // or whatever you want to do
        }
    }, interval);
}());

Şu anda olduğu gibi, bu kod hemen yürütülür ve 3 dakika hiçbir fare hareketi veya tuşa basılmadığında geçerli sayfanızı yeniden yükler.

Bu, boş zaman aşımlarını temiz ve bağımsız bir şekilde işlemek için düz vanilya JavaScript'i ve hemen çağrılan bir işlev ifadesi kullanır.


document.onclick, otomatik olarak yazdığım .trigger ('click') komutunu kullanarak javascript işlevlerini dikkate alır. Bu gerçekten bir kullanıcı etkileşimi değil, ancak bu durumda idleCounter'ı sıfırlayacak
Carmela

@Carmela: Bunu neden sadece gördüğümü bilmiyorum; Bunu kaçırmış olmalıyım. Teşekkürler, onclickmuhtemelen ek olarak gerekli olmadığından ödevi kaldırdım onmousemove, ancak programlı olarak tetiklenen bu olaylardan herhangi biri sıfırlanmaya devam edecek idleCounter. Sadece bir işlevi çağırmak yerine neden kullanıcı etkileşimini simüle edeceğinizden emin değilim, ancak bu bir nedenden dolayı yapmanız gereken bir şeyse, bu cevap sizin için işe yaramayacak, diğer cevapların çoğu bu soruya baktım.
johnnyRose

15

Bunun nispeten eski bir soru olduğunu biliyorum, ama aynı sorunu yaşadım ve oldukça iyi bir çözüm buldum.

Ben kullandım: jquery.idle ve sadece yapmanız gereken:

$(document).idle({
  onIdle: function(){
    alert('You did nothing for 5 seconds');
  },
  idle: 5000
})

JsFiddle demosuna bakın .

(Yalnızca Bilgi için: arka uç etkinlik izleme için buna bakın Tarayıcı yükünü açar )


Bu işlevi nasıl durdurabilirim, Bir olay boşta durdular: dur ama dürüstçe bunu nasıl kullanacağımı bilmiyorum. Ben sonraki sayfaya (ajax tabanlı böylece sadece HTML sayfasının bir parçası güncellendi) taşındı, boşta işlevi durur istiyorum. Bunu nasıl başaracağınızı biliyor muydunuz?
Mübarek

Burada şöyle diyor: "boşta: dur": kullanıcı izlemeyi durduracak ve kaldıracak
DDan

Zaten okudum ama bunu nasıl kullanacağımı anlayamadım, bana yardım eder misin?
Mübarek

Yalnızca bir kez tetiklenmesini istiyorsanız, keepTrackingseçeneği olarak ayarlayabilirsiniz false. Sıfırlamak istiyorsanız yeniden başlatmayı deneyebilirsiniz. İşte sadece bir kez ateşlenecek
DDan

Hayır bir kez ateş etmem, keepTracking doğru olmalı, ancak diğer sayfaya navigasyonda bunu durdurmak istiyorum
Mubasher

15

Önceki tüm yanıtlar her zaman etkin bir fare kaldırma işleyicisine sahiptir. İşleyici jQuery ise, jQuery'nin gerçekleştirdiği ek işleme eklenebilir. Özellikle kullanıcı bir oyun faresi kullanıyorsa, saniyede 500 olay gerçekleşebilir.

Bu çözüm, her fare kaldırma olayının işlenmesini önler. Bu, küçük bir zamanlama hatasıyla sonuçlanır, ancak ihtiyaçlarınıza göre ayarlayabilirsiniz.

function setIdleTimeout(millis, onIdle, onUnidle) {
    var timeout = 0;
    startTimer();

    function startTimer() {
        timeout = setTimeout(onExpires, millis);
        document.addEventListener("mousemove", onActivity);
        document.addEventListener("keydown", onActivity);
    }

    function onExpires() {
        timeout = 0;
        onIdle();
    }

    function onActivity() {
        if (timeout) clearTimeout(timeout);
        else onUnidle();
        //since the mouse is moving, we turn off our event hooks for 1 second
        document.removeEventListener("mousemove", onActivity);
        document.removeEventListener("keydown", onActivity);
        setTimeout(startTimer, 1000);
    }
}

http://jsfiddle.net/jndxq51o/


1
Bir sayfaya yerleştirilirse bu otomatik olarak çalışır mı yoksa $ (belge) .ready () sarıcısının içinde olması gerekir mi? Teşekkür ederim! Ayrıca, zamanlayıcının süresi dolduğunda bir eylem gerçekleştiren kısım nerede?
Oranges13

1
Bunu belge hazır olmadan önce istediğiniz zaman arayabilirsiniz. Zamanlayıcının süresi dolduğunda çağrılacak bir 'geri arama' işlevi iletirsiniz.
Sarsaparilla

1
Bu $(startTimer), eşdeğer $(document).ready(startTimer)ve tuş basma olaylarını bağlamadan önce DOM'un hazır olmasını sağlar.
Sarsaparilla

1
+1 Bu benim yaptığım şeydir - fare kırma işleyicileri durgunluğa ve pil ömrünün kısalmasına katkıda bulunur, bu nedenle küçük zamanlama hatasını karşılayabiliyorsanız, sadece periyodik olarak açmak harika bir fikirdir. Genellikle otomatik oturum sona erme uyarıları için boşta kalma süresi algılaması kullanıyorum (örneğin, "Hala orada mısın?"), Bu nedenle bir kullanıcının "boşta" duruma geçmesinden önce birkaç dakika geçirdim, bu durumda küçük bir zamanlama hatası tamamen önemsizdir.
keçi

1
Ok tuşlarını "tuşa basma" olayı tarafından algılanmadığından, "tuşa basma" işlevini "tuşa basma" dan daha iyidir. Dolayısıyla, kullanıcı ok tuşlarını kullanarak sayfada geziniyorsa, yine de Boşta olur.
aFerrer

13

Muhtemelen bir şeyleri formun gövdesinde fare hareketini algılayarak ve global bir değişkeni son hareket zamanı ile güncelleyerek bir araya getirebilirsiniz. Daha sonra, son hareket süresini periyodik olarak kontrol eden ve son fare hareketinin algılanmasından bu yana yeterince uzunsa bir şeyler yapan bir aralık zamanlayıcısına ihtiyacınız olacaktır.


Komut dosyasının, tüm kullanıcı girişlerini değil, yalnızca sayfanın gövdesindeki hareketi algılayabileceğini unutmayın. Javascript'ten CPU veya işlem bilgisi almanın bir yolu olduğunu düşünmüyorum.
Dave Swersky

1
Fikrinizi jQuery'de uygulama özgürlüğünü aldım.
Peter J

9

Boşta kalma zaman aşımına uğrayan etkinlikleri ve diğer durumlarda olayları algılamak için küçük bir ES6 sınıfı yazdım. Bu kapsar klavye, fare ve dokunmatik , olabilir aktive ve deaktive ve çok yalın bir API vardır:

const timer = new IdleTimer(() => alert('idle for 1 minute'), 1000 * 60 * 1);
timer.activate();

O mu değil sen eski tarayıcıları desteklemek için Babel aracılığıyla çalıştırmak gerekebilir rağmen, jQuery bağlıdır.

https://gist.github.com/4547ef5718fd2d31e5cdcafef0208096

Biraz geri bildirim aldığımda bir npm paketi olarak serbest bırakabilirim.


8

Desteklenen bir tarayıcıyı hedefliyorsanız (Aralık 2018 itibariyle Chrome veya Firefox) requestIdleCallback ile deneme yapabilir ve desteklenmeyen tarayıcılar için requestIdleCallback şemasını ekleyebilirsiniz .


Ve diğer tarayıcıları rahat bırak?
Frank Conijn

Shim tüm tarayıcıları kapsar. Ve bu tek cevaptı! Diğer yavaşlama cevapları fare ile ilgilidir. Etkileşim veya CPU yalnızca örnek olarak söylenmiştir. Bir fare çözümü ile CPU boşta nasıl tespit edilir?

6

Bu kodu deneyin, mükemmel çalışıyor.

var IDLE_TIMEOUT = 10; //seconds
var _idleSecondsCounter = 0;

document.onclick = function () {
    _idleSecondsCounter = 0;
};

document.onmousemove = function () {
    _idleSecondsCounter = 0;
};

document.onkeypress = function () {
    _idleSecondsCounter = 0;
};

window.setInterval(CheckIdleTime, 1000);

function CheckIdleTime() {
    _idleSecondsCounter++;
    var oPanel = document.getElementById("SecondsUntilExpire");
    if (oPanel)
        oPanel.innerHTML = (IDLE_TIMEOUT - _idleSecondsCounter) + "";
    if (_idleSecondsCounter >= IDLE_TIMEOUT) {
        alert("Time expired!");
        document.location.href = "SessionExpired.aspx";
    }
}

artı 1 vanilya js olduğu için
ayaz

5
<script type="text/javascript">
var idleTime = 0;
$(document).ready(function () {
    //Increment the idle time counter every minute.
    idleInterval = setInterval(timerIncrement, 60000); // 1 minute

    //Zero the idle timer on mouse movement.
    $('body').mousemove(function (e) {
     //alert("mouse moved" + idleTime);
     idleTime = 0;
    });

    $('body').keypress(function (e) {
      //alert("keypressed"  + idleTime);
        idleTime = 0;
    });



    $('body').click(function() {
      //alert("mouse moved" + idleTime);
       idleTime = 0;
    });

});

function timerIncrement() {
    idleTime = idleTime + 1;
    if (idleTime > 10) { // 10 minutes

        window.location.assign("http://www.google.com");
    }
}
</script> 

Kopyalanan ve yukarıdaki cevaplar değiştirilmiş olsa da, bu jquery kodu mükemmel olduğunu düşünüyorum! donot dosyanıza jquery kitaplığını dahil etmeyi unuttum!


4

Tüm bu çözümlerle ilgili sorun, doğru olmasına rağmen, PHP, .NET veya Coldfusion geliştiricileri için Application.cfc dosyasında oturum zaman aşımı değerli kümesini dikkate alırken pratik değildir. Yukarıdaki çözüm tarafından ayarlanan sürenin sunucu tarafı oturum zaman aşımı ile senkronize edilmesi gerekir. İkisi senkronize edilmezse, kullanıcılarınızı sadece hayal kırıklığına uğratacak ve şaşırtacak problemlerle karşılaşabilirsiniz. Örneğin, sunucu tarafı oturum zaman aşımı 60 dakikaya ayarlanmış olabilir, ancak JavaScript boşta kalma süresi yakalaması, kullanıcının tek bir sayfada geçirebileceği toplam süreyi artırdığından kullanıcının güvenli olduğuna inanabilir. Kullanıcı uzun bir form doldurmak için zaman harcamış olabilir ve daha sonra göndermek için gider. Oturum zaman aşımı, form gönderilmeden önce devreye girebilir. Kullanıcılarıma sadece 180 dakika veriyorum, ve ardından kullanıcının oturumunu otomatik olarak kapatmak için JavaScript'i kullanın. Temel olarak, yukarıdaki kodun bir kısmını kullanarak, basit bir zamanlayıcı oluşturmak için, ancak fare olayı yakalamadan. Bu şekilde, istemci tarafım ve sunucu tarafım zamanı mükemmel bir şekilde senkronize olur. Kullanıcı arayüzünüzdeki zamanı azaltacak şekilde gösterirseniz karışıklık olmaz. CMS'de her yeni sayfaya erişildiğinde, sunucu tarafı oturumu ve JavaScript zamanlayıcısı sıfırlanır. Basit ve zarif. Bir kullanıcı 180 dakikadan fazla tek bir sayfada kalırsa, öncelikle sayfada bir sorun olduğunu düşünüyorum. azaldıkça. CMS'de her yeni sayfaya erişildiğinde, sunucu tarafı oturumu ve JavaScript zamanlayıcısı sıfırlanır. Basit ve zarif. Bir kullanıcı 180 dakikadan fazla tek bir sayfada kalırsa, öncelikle sayfada bir sorun olduğunu düşünüyorum. azaldıkça. CMS'de her yeni sayfaya erişildiğinde, sunucu tarafı oturumu ve JavaScript zamanlayıcısı sıfırlanır. Basit ve zarif. Bir kullanıcı 180 dakikadan fazla tek bir sayfada kalırsa, öncelikle sayfada bir sorun olduğunu düşünüyorum.


1
Evet, bu yüzden sadece sunucu tarafı oturumlarından kurtulduktan ve her şeyi html dosyalarından yükledikten sonra yapıyorum.
Dan Parker

4

Ayarlanan sıfırlama süresi ve bağlamaları ile saf JavaScript addEventListener

(function() {

  var t,
    timeout = 5000;

  function resetTimer() {
    console.log("reset: " + new Date().toLocaleString());
    if (t) { 
      window.clearTimeout(t); 
    }
    t = window.setTimeout(logout, timeout);
  }

  function logout() {
    console.log("done: " + new Date().toLocaleString());
  }
  resetTimer();

  //And bind the events to call `resetTimer()`
  ["click", "mousemove", "keypress"].forEach(function(name) {
    console.log(name);
    document.addEventListener(name, resetTimer);
  });

}());

4

(Bu konuda daha önce Equiman'ın iyi temel mantığından kısmen esinlenmiştir.)

sessionExpiration.js


sessionExpiration.js hafif ancak etkili ve özelleştirilebilir. Bir kez uygulandığında, sadece bir satırda kullanın:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • Tüm sekmeleri etkilerTarayıcının yalnızca bir değil, .
  • Hiçbir bağımlılık olmadan saf JavaScript ile yazılmıştır . Tamamen müşteri tarafı.
  • (Böylece isterse.) Has uyarı afiş ve geri sayım kullanıcı etkileşimi tarafından iptal edilir saati.
  • Sadece sessionExpiration.js dosyasını ekleyin ve işlevi, kullanıcı oturumu kapatıncaya kadar [1] boşta dakika (tüm sekmelerde) sayısı , [2] uyarı ve geri sayım görüntülenene kadar boşta kalan dakika sayısı ve [3] çıkış URL'si.
  • CSS'yi stil sayfanıza yerleştirin. İsterseniz özelleştirin. (Veya istemiyorsanız afişi atlayıp silin.)
  • Eğer varsa bunu ancak uyarı afiş istiyorum, o zaman kimliği ile boş bir div koymak gerekir sessExpirDiv sayfanızda (bir öneri Altbilgideki demek bile) .
  • Şimdi, tüm sekmeler belirtilen süre boyunca etkin değilse kullanıcı otomatik olarak oturumu kapatır.
  • İsteğe bağlı: İşlevle dördüncü bir bağımsız değişken (URL serverRefresh) sağlayabilirsiniz, böylece sayfayla etkileşim kurduğunuzda sunucu tarafı oturum zamanlayıcısı da yenilenir.

Bu, CSS'yi değiştirmezseniz, eylemde nasıl göründüğüne bir örnektir.

demo_image


3

Aradığınızı yapacak basit bir jQuery eklentisi yazdım.

https://github.com/afklondon/jquery.inactivity

$(document).inactivity( {
    interval: 1000, // the timeout until the inactivity event fire [default: 3000]
    mouse: true, // listen for mouse inactivity [default: true]
    keyboard: false, // listen for keyboard inactivity [default: true]
    touch: false, // listen for touch inactivity [default: true]
    customEvents: "customEventName", // listen for custom events [default: ""]
    triggerAll: true, // if set to false only the first "activity" event will be fired [default: false]
});

Komut dosyası, fare, klavye, dokunma ve diğer özel etkinlik hareketsizliğini (boşta) dinler ve genel "etkinlik" ve "hareketsizlik" olaylarını tetikler.

Bu yardımcı olur umarım :)


Gerçekten bir gecikmeye ihtiyaç var mı, özel bir olay işleyicisinden özel bir olayı tetiklemiyor mu?
Hibou57

2

Sadece birkaç düşünce, keşfetmek için bir veya iki yol.

Bir fonksiyonun her 10 saniyede bir çalıştırılması ve bir "sayaç" değişkenini kontrol ettirmesi mümkün müdür? Bu mümkün ise, sayfa için fareyle üzerine gelme yapabilirsiniz, değil mi? Öyleyse, "counter" değişkenini sıfırlamak için fareyle üzerine gelme olayını kullanın. İşleviniz çağrılırsa ve sayaç önceden belirlediğiniz aralığın üzerindeyse, eyleminizi yapın.

Yine, sadece bazı düşünceler ... Umarım yardımcı olur.


2

Bu kod çalışma dosyasını test ettim:

var timeout = null;
    var timee = '4000'; // default time for session time out.
    $(document).bind('click keyup mousemove', function(event) {

    if (timeout !== null) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
              timeout = null;
            console.log('Document Idle since '+timee+' ms');
            alert("idle window");
        }, timee);
    });

2

Bulduğum en iyi çözüm: http://css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/

İşte JS:

idleTimer = null;
idleState = false;
idleWait = 2000;

(function ($) {

    $(document).ready(function () {

        $('*').bind('mousemove keydown scroll', function () {

            clearTimeout(idleTimer);

            if (idleState == true) { 

                // Reactivated event
                $("body").append("<p>Welcome Back.</p>");            
            }

            idleState = false;

            idleTimer = setTimeout(function () { 

                // Idle Event
                $("body").append("<p>You've been idle for " + idleWait/1000 + " seconds.</p>");

                idleState = true; }, idleWait);
        });

        $("body").trigger("mousemove");

    });
}) (jQuery)

2

Aşağıdaki çözümü kullanabilirsiniz

var idleTime;
$(document).ready(function () {
         reloadPage();
        $('html').bind('mousemove click mouseup mousedown keydown keypress keyup submit change mouseenter scroll resize dblclick', function () {
            clearTimeout(idleTime);
            reloadPage();
        });
});
function reloadPage() {
    clearTimeout(idleTime);
    idleTime = setTimeout(function () {
        location.reload();
    }, 3000);
}

2

Bu yaklaşımı kullanıyorum, çünkü bir olayın tetiklendiği zamanı sürekli olarak sıfırlamanıza gerek yoktur, bunun yerine sadece zamanı kaydederiz, bu boşta başlama noktasını oluşturur.

           function idle(WAIT_FOR_MINS, cb_isIdle) {
            var self = this, 
                idle,
                ms = (WAIT_FOR_MINS || 1) * 60000,
                lastDigest = new Date(),
                watch;
            //document.onmousemove = digest;
            document.onkeypress = digest;
            document.onclick = digest;

            function digest() {
               lastDigest = new Date(); 
            }
            // 1000 milisec = 1 sec
            watch = setInterval(function(){
                if (new Date() - lastDigest > ms && cb_isIdel) {
                    clearInterval(watch);
                    cb_isIdle();
                }

            }, 1000*60);    
        },

1

Muhtemelen listelenen fare kırma hilelerini kullanarak web sayfanızdaki hareketsizliği tespit edebilirsiniz, ancak bu size kullanıcının başka bir pencerede veya sekmede başka bir sayfada olmadığını veya kullanıcının Word veya Photoshop veya WOW'da olduğunu ve şu anda sayfanıza bakmıyor. Genellikle önceden getirmeyi yaparım ve müşterinin çoklu görevine güvenirim. Bu işlevselliğe gerçekten ihtiyacınız varsa , Windows'ta bir activex kontrolü ile bir şey yaparsınız, ancak en iyi ihtimalle çirkin.


1

İşte Angular'da başarmak için bir AngularJS hizmeti.

/* Tracks now long a user has been idle.  secondsIdle can be polled 
   at any time to know how long user has been idle. */
fuelServices.factory('idleChecker',['$interval', function($interval){
    var self = {
        secondsIdle: 0,
        init: function(){
            $(document).mousemove(function (e) {
                self.secondsIdle = 0;
            });
            $(document).keypress(function (e) {
                self.secondsIdle = 0;
            });
            $interval(function(){
                self.secondsIdle += 1;
            }, 1000)
        }
    }
    return self;
}]);

Bu boş denetleyicinin tüm yollar için çalışacağını unutmayın, bu nedenle .run()açısal uygulamanın yükünde başlatılmalıdır . Sonra idleChecker.secondsIdleher rotanın içinde kullanabilirsiniz .

myApp.run(['idleChecker',function(idleChecker){
    idleChecker.init();
}]);

1

Debounce aslında harika bir fikir! İşte jQuery ücretsiz projeler için sürüm:

const derivedLogout = createDerivedLogout(30);
derivedLogout(); // it could happen that user too idle)
window.addEventListener('click', derivedLogout, false);
window.addEventListener('mousemove', derivedLogout, false);
window.addEventListener('keyup', derivedLogout, false); 

function createDerivedLogout (sessionTimeoutInMinutes) {
    return _.debounce( () => {
        window.location = this.logoutUrl;
    }, sessionTimeoutInMinutes * 60 * 1000 ) 
}

1

Mümkün olduğunca basit, yalnızca farenin ne zaman hareket ettiğini tespit edin:

var idle = false;

document.querySelector('body').addEventListener('mousemove', function(e) {
    if(idle!=false)idle = false;
});

var idleI = setInterval(function()
{   
    if(idle == 'inactive')
    {
        return;
    }

    if(idle == true)
    {
        idleFunction();
        idle = 'inactive';
        return;
    }

    idle = true;
}, 30000);// half the expected time, idle will trigger after 60s in this case.

function idleFuntion()
{
   console.log('user is idle');
}

0

Belge gövdesine bir zamanlayıcıyı sıfırlayan bir tıklama veya fareyle üzerine gelme olayı ekleyebilirsiniz. Zamanlayıcının belirli bir süreyi (1000 milis gibi) geçip geçmediğini kontrol eden ve ön yüklemenizi başlatan zamanlanmış aralıklarla aradığınız bir işleve sahip olun.


0

Javascript'in CPU kullanımını söylemenin bir yolu yoktur. Bu sandbox javascript içeride çalışmasını kıracak.

Bunun dışında, sayfanın üst düzey ve onkeydown olaylarını takmak muhtemelen işe yarayabilir.

Gecikme sonrasında çağrılacak bir işlevi zamanlamak için onload olayında use setTimeout öğesini de ayarlayabilirsiniz.

// Call aFunction after 1 second
window.setTimeout(aFunction, 1000);

3
Acaba bu cevapta neden bu kadar çok düşüş var. Görebildiğim kadarıyla, sorulan soruya cevap verdi ve aslında doğrudur. Sadece ayrıntılı kod örnekleri sunmaya devam etmedi.
Ifedi Okonkwo

1
Artık "bir çerçevenin sonunda boş zaman olduğunda veya kullanıcı etkin olmadığında" javascript işlevini çağırabilirsiniz. Developers.google.com/web/updates/2015/08/…
Max

setTimeout 0, arabellek ne kadar dolu olduğunu hesaplamak için FILO
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.