Làm cách nào để phát hiện thời gian nhàn rỗi trong JavaScript một cách thanh lịch?


478

Có thể phát hiện thời gian " nhàn rỗi " trong JavaScript không?
Trường hợp sử dụng chính của tôi có lẽ sẽ là tìm nạp trước hoặc tải trước nội dung.

Thời gian nhàn rỗi: Thời gian người dùng không hoạt động hoặc không sử dụng CPU


7
Làm thế nào để bạn xác định IDLE TIME?
Itay Moav -Malimovka 20/03/2016


74
Gần 50% câu trả lời ở đây đã sử dụng jQuery cho một nhiệm vụ đơn giản như vậy đối với Javascript thuần túy. Nó vượt quá giới hạn, đặc biệt là OP muốn Javascript. Yêu cầu kem Dâu nhưng thay vào đó là một chuồng bán tách rời.
TheCarver

4
đó là StackOverflow dành cho bạn
robertmain

5
@TheCarver - Phải cài đặt một thư viện jQuery cho một cái gì đó quá đơn giản thực sự là vô lý, và nó kéo dài thời gian kết xuất và tăng mức sử dụng năng lượng. Mọi người nên cuộn xuống một chút nữa. Cũng có một giải pháp sao chép-dán trong vanilla Javascript.
Frank Conijn

Câu trả lời:


438

Đây là một tập lệnh đơn giản sử dụng JQuery để xử lý các sự kiện mousemove và nhấn phím. Nếu hết thời gian, trang tải lại.

<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
Bạn đang thiếu dấu chấm phẩy sau phần thân $ (tài liệu). Đã (hàm (). Ngoài ra, trong lệnh gọi setInterval, nó sẽ không hoạt động với dấu ngoặc kép quanh tên hàm và bạn không cần dấu ngoặc đơn sau nó. Chỉ cần: setInterval (timerIncrement, 60000)
Jesse Roper

9
@Jlie: Đề xuất của bạn đều tốt, đây là cách mã phải như vậy. Nhưng tôi chỉ muốn chỉ ra rằng ngay cả khi không có những thay đổi này, mã vẫn có đầy đủ chức năng. Dấu chấm phẩy ở cuối câu lệnh biểu thức là tùy chọn và trên thực tế bạn có thể chuyển một chuỗi tới setInterval, sau đó được đánh giá là JavaScript.
Felix Kling

6
Bạn chỉ có thể sử dụng idleTime++;thay vìidleTime = idleTime + 1;
Mike Causer

7
Đây không phải là nặng trên hệ thống của người dùng? Giả sử, một người dùng có trình duyệt khá cũ trên một máy tính không quá nặng, đang làm việc trong một ứng dụng javascript trong nửa ngày và nó đang xử lý các chức năng này mỗi khi người dùng di chuyển chuột của mình ... Tôi tự hỏi liệu điều này có thắng không ' t ảnh hưởng đến trải nghiệm của người dùng ...
Sander

5
@PietBinnenbocht Ngoài ra, nếu bạn bắt đầu tối ưu hóa những thứ như thế này, bạn cũng có thể thay đổi mọi hàm có chuỗi muốn 'mousemove keydown click'sử dụng cờ bit ( Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK), vì chúng nhanh hơn so với thao tác chuỗi. Nhưng bạn có thực sự muốn làm điều này?
Killah

361

Không sử dụng jQuery, chỉ có JavaScript vanilla:

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
    }
};

Và khởi tạo hàm nơi bạn cần nó (ví dụ: onPageLoad).

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

Bạn có thể thêm nhiều sự kiện DOM nếu bạn cần. Được sử dụng nhiều nhất là:

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

Hoặc đăng ký các sự kiện mong muốn bằng cách sử dụng một mảng

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

Danh sách sự kiện DOM : http://www.w3schools.com/jsref/dom_obj_event.asp

Nhớ sử dụng window, hoặc documenttheo nhu cầu của bạn. Ở đây bạn có thể thấy sự khác biệt giữa chúng: Sự khác biệt giữa cửa sổ, màn hình và tài liệu trong Javascript là gì?

Mã được cập nhật với @ frank-conijn và @daxchen cải thiện: window.onscrollsẽ không kích hoạt nếu cuộn nằm trong phần tử có thể cuộn, vì các sự kiện cuộn không bong bóng. window.addEventListener('scroll', resetTimer, true), đối số thứ ba cho người nghe biết sự kiện bắt trong giai đoạn chụp thay vì pha bong bóng.


58
Tôi thích cách tiếp cận javascript đơn giản hơn nhiều.
Manatax

4
chắc chắn đặt lại bộ hẹn giờ là một cách tiếp cận trực tiếp / trực quan và chính xác hơn so với việc hết thời gian thực hiện công việc của mình, chỉ để giữ số nguyên của một thứ khác, khi bộ đếm thời gian có thể trở thành bộ đếm (độ chính xác cao).
Josh Sutterfield

2
@mpsbhat chỉ cần thêm console.log hoặc cảnh báo xem nếu hoạt động. Hoặc đăng ký sự kiện này:document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
Equiman

2
Vâng ... Làm việc. jsfiddle.net/mpsbhat/6b6mja5t/1 . Cảm ơn @equiman
mpsbhat

6
Sẽ tốt hơn nhiều nếu có một lá cờ var notidle; đặt cờ đó = true chỉ trên các sự kiện. Sau đó, trong kiểm tra chức năng resetTimer nếu cờ notidle là true, nếu nó được đặt lại bộ hẹn giờ của họ hoặc đăng xuất cuộc gọi. Điều này sẽ loại bỏ chi phí phức tạp của việc liên tục đặt lại bộ hẹn giờ.
MartinWebb

75

Cải thiện câu trả lời của Equiman:

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();

.
Ngoài những cải tiến liên quan đến phát hiện hoạt động và thay đổi từ documentsang window, tập lệnh này thực sự gọi hàm, thay vì để nó ở trạng thái chờ.

Nó không bắt được mức sử dụng CPU trực tiếp, nhưng điều đó là không thể, bởi vì thực thi một chức năng gây ra việc sử dụng CPU. Và người dùng không hoạt động cuối cùng dẫn đến việc sử dụng CPU bằng không, do đó, gián tiếp nó không sử dụng CPU.


3
Chỉ muốn chỉ ra rằng window.onscrollsẽ không kích hoạt nếu cuộn nằm trong một yếu tố có thể cuộn được, bởi vì các sự kiện cuộn không bong bóng. Sử dụng window.addEventListener('scroll', resetTimer, true), đối số thứ ba bảo người nghe nắm bắt sự kiện trong capturegiai đoạn thay vì bubblepha (IE> 8), xem câu trả lời này
DaxChen

@DaxChen - Không document.onscrollcó vấn đề tương tự, không kích hoạt nếu cuộn ở trong một đứa trẻ có thể cuộn?
Frank Conijn

2
Vâng, điểm tôi đã nói là sử dụng addEventListenerthay vì onscroll.
DaxChen

@DaxChen - OK, tôi đã tự hỏi liệu bạn có ý đó, để giải quyết nó, nhưng giờ thì rõ rồi. Tôi chỉnh sửa câu trả lời cho phù hợp. Cảm ơn các bình luận.
Frank Conijn

Tôi sẽ cập nhật câu trả lời của mình với thông tin quan trọng này, để tránh bản sao khác và dán lỗi của tôi. Cảm ơn @DaxChen và Frank
equiman

33

Tôi đã tạo ra một lib nhỏ mà làm điều này một năm trước:

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

Sự miêu tả:

Thư viện javascript nhỏ để báo cáo hoạt động của người dùng trong trình duyệt (đi vắng, không sử dụng trang web, trong một tab khác, v.v.). đó là độc lập với bất kỳ thư viện javascript khác như jquery.

Người dùng Visual Studio có thể lấy nó từ NuGet bằng cách: PM> Install-Package Idle.js


32

Đây là một triển khai jQuery sơ bộ về ý tưởng của tvanfosson:

$(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
Giải pháp này không xem xét các sự kiện bàn phím.
Daniel Silveira

7
Không bao giờ vượt qua setIntervalmột chuỗi! Chỉ cần cung cấp một chức năng như một biến!
Eric

1
Điều này sẽ không thực sự hoạt động vì thông qua một chuỗi để setInterval()đánh giá biểu thức trong phạm vi toàn cầu và do đó nó sẽ không tìm thấy timerIncrement()hàm bên trong hàm xử lý.. Đây là một lý do khác để KHÔNG BAO GIỜ chuyển chuỗi sang setInterval(). Chỉ cần vượt qua một tham chiếu chức năng thực tế và bạn sẽ không gặp vấn đề này bởi vì chúng được đánh giá trong phạm vi hiện tại.
jfriend00

Cảm ơn, tôi đã không nhận thức được sự cần thiết KHÔNG BAO GIỜ chuyển chuỗi sang setInterval. Cập nhật câu trả lời của tôi.
Peter J

24

Tương tự như giải pháp của Iconic ở trên (với sự kiện tùy chỉnh jQuery) ...

// 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

Bạn có thể làm điều đó thanh lịch hơn với dấu gạch dướijquery -

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

16

Câu trả lời của tôi được lấy cảm hứng từ câu trả lời của vijay , nhưng là một giải pháp ngắn gọn, tổng quát hơn mà tôi nghĩ tôi muốn chia sẻ cho bất kỳ ai mà nó có thể giúp ích.

(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);
}());

Vì hiện tại, mã này sẽ thực thi ngay lập tức và tải lại trang hiện tại của bạn sau 3 phút không di chuyển chuột hoặc nhấn phím.

Điều này sử dụng JavaScript vanilla đơn giản và một biểu thức hàm được gọi ngay lập tức để xử lý thời gian chờ nhàn rỗi một cách sạch sẽ và khép kín.


document.onclick xem xét các hàm javascript bằng cách sử dụng .trigger ('click') mà tôi đã viết dưới dạng tự động. Vì vậy, đây không thực sự là tương tác của người dùng nhưng nó sẽ thiết lập lại idleCount trong trường hợp này
Carmela

@Carmela: Tôi không chắc tại sao tôi chỉ nhìn thấy điều này; Tôi phải đã bỏ lỡ nó. Cảm ơn, tôi đã xóa onclickbài tập vì có lẽ không cần thiết ngoài onmousemove, nhưng rõ ràng bất kỳ sự kiện nào được kích hoạt theo chương trình sẽ tiếp tục được đặt lại idleCounter. Tôi không chắc tại sao bạn mô phỏng tương tác của người dùng thay vì chỉ gọi một chức năng, nhưng nếu đó là điều bạn cần làm vì một số lý do, câu trả lời này rõ ràng sẽ không hiệu quả với bạn, cũng như hầu hết các câu trả lời khác tôi sẽ đã xem xét câu hỏi này.
johnnyRose

15

Tôi biết đó là một câu hỏi tương đối cũ, nhưng tôi có cùng một vấn đề và tôi đã tìm thấy một giải pháp khá tốt.

Tôi đã sử dụng: jquery.idle và tôi chỉ cần làm:

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

Xem bản demo của JsFiddle .

(Chỉ để biết thông tin: xem phần này để theo dõi sự kiện phía sau Tải trình duyệt )


Làm thế nào tôi có thể dừng chức năng này, Họ tuyên bố một sự kiện nhàn rỗi: dừng lại nhưng tôi thực sự không biết làm thế nào để sử dụng chức năng này. Tôi muốn rằng nếu tôi chuyển sang trang tiếp theo (dựa trên ajax để chỉ một đoạn trang HTML được cập nhật) thì chức năng nhàn rỗi dừng lại. Bạn có biết làm thế nào để đạt được điều này?
Mubasher

Ở đây có ghi: "idle: stop": sẽ dừng và xóa theo dõi người dùng
DDan

Tôi đã đọc nhưng không thể tìm ra cách sử dụng cái này, bạn có thể giúp tôi không?
Mubasher

Nếu bạn muốn nó chỉ bắn một lần, bạn có thể đặt keepTrackingtùy chọn thành false. Nếu bạn muốn thiết lập lại, bạn có thể thử khởi động lại. Dưới đây là một ví dụ sửa đổi sẽ chỉ bắn một lần: jsfiddle.net/f238hchm/12
DDan

Không, tôi không bắn một lần, keepTracking phải là sự thật, nhưng khi điều hướng đến trang khác tôi muốn dừng việc này
Mubasher

15

Tất cả các câu trả lời trước có một trình xử lý mousemove luôn hoạt động. Nếu trình xử lý là jQuery, thì quá trình xử lý bổ sung mà jQuery thực hiện có thể tăng lên. Đặc biệt nếu người dùng đang sử dụng chuột chơi game, có thể xảy ra tới 500 sự kiện mỗi giây.

Giải pháp này tránh xử lý mọi sự kiện mousemove. Điều này dẫn đến một lỗi thời gian nhỏ, nhưng bạn có thể điều chỉnh theo nhu cầu của mình.

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
Điều này sẽ tự động hoạt động nếu được đặt trên một trang, hoặc nó cần phải nằm trong một trình bao bọc $ (tài liệu). Yet ()? Cảm ơn bạn! Ngoài ra, đâu là phần thực hiện một hành động khi hết giờ?
Oranges13

1
Bạn có thể gọi đây bất cứ lúc nào, ngay cả trước khi tài liệu đã sẵn sàng. Bạn chuyển một hàm 'gọi lại' sẽ được gọi khi hết giờ.
Sarsaparilla

1
Điều $(startTimer)này tương đương với $(document).ready(startTimer), đảm bảo rằng DOM đã sẵn sàng trước khi bạn kết nối các sự kiện mousemove và nhấn phím.
Sarsaparilla

1
+1 Đây là những gì tôi làm - trình xử lý mousemove góp phần làm chậm và giảm tuổi thọ pin, vì vậy chỉ bật định kỳ là một ý tưởng tuyệt vời nếu bạn có thể đủ khả năng mắc lỗi thời gian nhỏ. Tôi thường sử dụng tính năng phát hiện thời gian nhàn rỗi để cảnh báo hết hạn phiên tự động (ví dụ: "Bạn vẫn ở đó chứ?"), Vì vậy tôi có xu hướng có nhiều phút trước khi người dùng "không sử dụng", trong trường hợp đó, một lỗi thời gian nhỏ hoàn toàn không liên quan.

1
Tốt hơn là sử dụng "phím tắt" so với "nhấn phím" vì các phím mũi tên không được phát hiện bởi sự kiện "nhấn phím". Vì vậy, nếu người dùng đang điều hướng trang bằng các phím mũi tên, nó sẽ trở thành Idle anyways.
aFerrer

13

Bạn có thể có thể hack một cái gì đó cùng nhau bằng cách phát hiện chuyển động của chuột trên cơ thể của biểu mẫu và cập nhật một biến toàn cục với thời gian di chuyển cuối cùng. Sau đó, bạn cần phải có một bộ định thời khoảng thời gian chạy để kiểm tra định kỳ thời gian di chuyển cuối cùng và thực hiện một cái gì đó nếu nó đã đủ dài kể từ khi di chuyển chuột cuối cùng được phát hiện.


Điều quan trọng cần lưu ý là tập lệnh sẽ chỉ có thể phát hiện chuyển động trên thân trang chứ không phải tất cả đầu vào của người dùng. Tôi không nghĩ có cách nào để lấy CPU hoặc xử lý thông tin từ javascript.
Dave Swersky

1
Tôi đã tự do thực hiện ý tưởng của bạn trong jQuery.
Peter J

9

Tôi đã viết một lớp ES6 nhỏ để phát hiện hoạt động và nếu không thì bắn các sự kiện khi hết thời gian rảnh. Nó bao gồm bàn phím, chuột và cảm ứng , có thể được kích hoạt và hủy kích hoạt và có API rất gọn gàng:

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

không phụ thuộc vào jQuery, mặc dù bạn có thể cần chạy nó qua Babel để hỗ trợ các trình duyệt cũ hơn.

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

Tôi có thể phát hành nó dưới dạng gói npm sau khi nhận được một số phản hồi.


8

Nếu bạn đang nhắm mục tiêu một trình duyệt được hỗ trợ (Chrome hoặc Firefox kể từ tháng 12 năm 2018), bạn có thể thử nghiệm requestIdleCallback và bao gồm shim requestIdleCallback cho các trình duyệt không được hỗ trợ.


Và các trình duyệt khác một mình?
Frank Conijn

Shim bao gồm tất cả các trình duyệt. Và đây là câu trả lời duy nhất! Câu trả lời chậm khác là về chuột. Sự tương tác hoặc CPU chỉ được nói là một ví dụ. Làm thế nào để phát hiện CPU nhàn rỗi với một giải pháp chuột?

6

Hãy thử mã này, nó hoạt động hoàn hảo.

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";
    }
}

cộng 1 cho là js vani
frostymarvelous

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> 

Tôi nghĩ rằng mã jquery này là hoàn hảo, mặc dù được sao chép và sửa đổi từ các câu trả lời ở trên !! đừng quên bao gồm thư viện jquery trong tập tin của bạn!


4

Mặc dù vấn đề với tất cả các giải pháp này là chính xác nhưng chúng không thực tế, khi tính đến tập hợp thời gian chờ phiên có giá trị, sử dụng PHP, .NET hoặc trong tệp Application.cfc cho các nhà phát triển Coldfusion. Thời gian được đặt bởi giải pháp trên cần đồng bộ hóa với thời gian chờ phiên phía máy chủ. Nếu cả hai không đồng bộ hóa, bạn có thể gặp phải sự cố sẽ khiến người dùng của bạn thất vọng và bối rối. Ví dụ: thời gian chờ phiên phía máy chủ có thể được đặt thành 60 phút, nhưng người dùng có thể tin rằng mình an toàn, vì thời gian nhàn rỗi JavaScript đã tăng tổng thời gian người dùng có thể dành cho một trang. Người dùng có thể đã dành thời gian điền vào một biểu mẫu dài, và sau đó đi gửi nó. Thời gian chờ phiên có thể bắt đầu trước khi quá trình gửi biểu mẫu được xử lý. Tôi có xu hướng chỉ cung cấp cho người dùng của mình 180 phút, và sau đó sử dụng JavaScript để tự động đăng xuất người dùng. Về cơ bản, sử dụng một số mã ở trên, để tạo một bộ đếm thời gian đơn giản, nhưng không có phần sự kiện bắt chuột. Theo cách này, thời gian phía máy khách và phía máy chủ của tôi đồng bộ hóa hoàn hảo. Không có sự nhầm lẫn, nếu bạn hiển thị thời gian cho người dùng trong giao diện người dùng của bạn, vì nó giảm. Mỗi khi một trang mới được truy cập trong CMS, phiên máy chủ & bộ đếm thời gian JavaScript được đặt lại. Đơn giản & thanh lịch. Nếu một người dùng ở lại trên một trang trong hơn 180 phút, tôi cho rằng có điều gì đó không ổn với trang đó, ngay từ đầu. khi nó giảm Mỗi khi một trang mới được truy cập trong CMS, phiên máy chủ & bộ đếm thời gian JavaScript được đặt lại. Đơn giản & thanh lịch. Nếu một người dùng ở lại trên một trang trong hơn 180 phút, tôi cho rằng có điều gì đó không ổn với trang đó, ngay từ đầu. khi nó giảm Mỗi lần một trang mới được truy cập trong CMS, phiên phía máy chủ & JavaScript giờ là thiết lập lại. Đơn giản & thanh lịch. Nếu một người dùng ở lại trên một trang trong hơn 180 phút, tôi cho rằng có điều gì đó không ổn với trang đó, ngay từ đầu.


1
Đúng, đó là lý do tại sao tôi chỉ làm điều này sau khi thoát khỏi các phiên phía máy chủ và tải mọi thứ từ các tệp html.
Dan Parker

4

JavaScript thuần với thời gian đặt lại và các ràng buộc thông qua 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

(Một phần lấy cảm hứng từ logic cốt lõi tốt của Equiman trước đó trong chủ đề này.)

sessionExpirst.js


sessionExpirst.js rất nhẹ nhưng hiệu quả và có thể tùy chỉnh. Sau khi thực hiện, sử dụng chỉ trong một hàng:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • Ảnh hưởng đến tất cả các tab của trình duyệt, không chỉ một.
  • Viết bằng JavaScript thuần , không có phụ thuộc. Phía khách hàng đầy đủ.
  • (Nếu muốn.)biểu ngữ cảnh báo và đồng hồ đếm ngược , điều đó bị hủy bởi tương tác của người dùng.
  • Chỉ cần bao gồm sessionExpirst.js và gọi hàm, với các đối số [1] số phút nhàn rỗi (trên tất cả các tab) cho đến khi người dùng đăng xuất, [2] số phút nhàn rỗi cho đến khi cảnh báo và đếm ngược được hiển thị và [3] url đăng xuất.
  • Đặt CSS trong biểu định kiểu của bạn. Tùy chỉnh nó nếu bạn thích. (Hoặc bỏ qua và xóa banner nếu bạn không muốn.)
  • Nếu bạn làm muốn biểu ngữ cảnh báo tuy nhiên, sau đó bạn phải đặt một div trống với ID sessExpirDiv trên trang của bạn (một gợi ý là đặt nó ở chân) .
  • Bây giờ người dùng sẽ tự động đăng xuất nếu tất cả các tab không hoạt động trong khoảng thời gian nhất định.
  • Tùy chọn: Bạn có thể cung cấp đối số thứ tư (URL serverRefresh) cho hàm, để bộ hẹn giờ phiên phía máy chủ cũng được làm mới khi bạn tương tác với trang.

Đây là một ví dụ về những gì nó trông giống như trong hành động, nếu bạn không thay đổi CSS.

demo_image


3

Tôi đã viết một plugin jQuery đơn giản sẽ làm những gì bạn đang tìm kiế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]
});

Kịch bản sẽ lắng nghe chuột, bàn phím, cảm ứng và các sự kiện tùy chỉnh không hoạt động (nhàn rỗi) và kích hoạt các sự kiện "hoạt động" và "không hoạt động" toàn cầu.

Hi vọng điêu nay co ich :)


Có thực sự cần một sự chậm trễ, không kích hoạt một sự kiện tùy chỉnh từ một trình xử lý sự kiện tùy chỉnh đủ?
Hibou57

2

Chỉ cần một vài suy nghĩ, một hoặc hai con đường để khám phá.

Có thể có một chức năng chạy cứ sau 10 giây và kiểm tra biến "bộ đếm" không? Nếu điều đó là có thể, bạn có thể di chuột qua trang, bạn có thể không? Nếu vậy, hãy sử dụng sự kiện di chuột để đặt lại biến "bộ đếm". Nếu chức năng của bạn được gọi và bộ đếm nằm trên phạm vi mà bạn xác định trước, thì hãy thực hiện hành động của bạn.

Một lần nữa, chỉ là một vài suy nghĩ ... Hy vọng nó sẽ giúp.


2

Tôi đã kiểm tra tập tin làm việc mã này:

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

Đây là giải pháp tốt nhất tôi đã tìm thấy: http://css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/

Đây là 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

Bạn có thể sử dụng giải pháp được đề cập dưới đây

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

Tôi sử dụng phương pháp này, vì bạn không cần phải liên tục đặt lại thời gian khi một sự kiện diễn ra, thay vào đó chúng tôi chỉ ghi lại thời gian, điều này tạo ra điểm bắt đầu nhàn rỗi.

           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

Bạn có thể có thể phát hiện sự không hoạt động trên trang web của mình bằng các thủ thuật mousemove được liệt kê, nhưng điều đó sẽ không cho bạn biết rằng người dùng không ở trên một trang khác trong một cửa sổ hoặc tab khác, hoặc người dùng đang ở trong Word hoặc Photoshop, hoặc WOW và chỉ không nhìn vào trang của bạn tại thời điểm này. Nói chung, tôi chỉ cần thực hiện tìm nạp trước và dựa vào đa tác vụ của khách hàng. Nếu bạn thực sự cần chức năng này, bạn sẽ làm một cái gì đó với điều khiển activex trong windows, nhưng tốt nhất là xấu.


1

Đây là một dịch vụ AngularJS để thực hiện trong Angular.

/* 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;
}]);

Hãy nhớ rằng trình kiểm tra nhàn rỗi này sẽ chạy cho tất cả các tuyến, vì vậy nó nên được khởi tạo .run()khi tải ứng dụng góc. Sau đó, bạn có thể sử dụng idleChecker.secondsIdlebên trong mỗi tuyến đường.

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

1

Ra mắt thực sự là một ý tưởng tuyệt vời! Đây là phiên bản cho các dự án miễn phí của jQuery:

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

Đơn giản như nó có thể nhận được, phát hiện khi chuột chỉ di chuyển:

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

Vâng, bạn có thể đính kèm một sự kiện nhấp chuột hoặc mousemove vào thân tài liệu đặt lại bộ hẹn giờ. Có một chức năng mà bạn gọi theo các khoảng thời gian để kiểm tra xem bộ định thời có quá thời gian quy định không (như 1000 mili) và bắt đầu tải trước.


0

Javascript không có cách nào để nói về việc sử dụng CPU. Điều này sẽ phá vỡ javascript hộp cát chạy bên trong.

Ngoài ra, việc kết nối các sự kiện onmouseover và onkeydown của trang có thể sẽ hiệu quả.

Bạn cũng có thể đặt sử dụng setTimeout trong sự kiện onload để lên lịch cho hàm được gọi sau khi trì hoãn.

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

3
Tôi tự hỏi tại sao rất nhiều downvote về câu trả lời này. Theo như tôi có thể thấy, nó đã trả lời câu hỏi được hỏi, và thực tế là chính xác. Chỉ không tiếp tục đưa ra các ví dụ mã phức tạp.
Ifedi Okonkwo

1
Bây giờ nó có thể gọi một hàm javascript khi "có thời gian rảnh rỗi vào cuối của một khung hình, hoặc khi người dùng không hoạt động." Developers.google.com/web/updates/2015/08/...
Max

setTimeout 0 có lẽ đúng hơn để tính toán trong avarage mức độ đầy đủ của bộ đệm bằng cách dành thời gian giữa FILO
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.