2014-07-14 59 views
3

我有一个托管仪表板的网站:我可以编辑页面上的JavaScript,并且每隔五秒钟刷新一次。在JavaScript中,我如何在特定的时间运行一个函数?

我想现在得到一个window.print()每天上午8点运行。

我该怎么做?

+12

在网页上的JavaScript *真的不听起来像这个合适的工具... – David

+4

JS没有固定时间的调度功能。您可以抽出当前时间,找出上午8点的时间,并为该时间间隔设置超时时间。但是,除非您在该页面上打开浏览器,否则这一切都毫无意义。只要在html中使用一些JS,在页面实际上在浏览器中查看之前,不会使其可执行,或者您正在使用服务器端JS,如node.js –

+0

我想你正在使用setInterval方法。在该方法中,看看早上8点和当前时间之间的差异是否小于5秒。如果是这样,请使用setTimeOut进行打印,并使用时间差。但您的浏览器需要在当时打开 – Subin

回答

21

JavaScript是不是这个工具。如果你想每天在特定时间运行某些东西,那么几乎可以肯定地寻找本地运行的东西,例如


但是,让我们考虑一下JavaScript是您唯一的选择。有几种方法可以做到这一点,但我会给你最简单的。

首先,您必须创建一个new Date()并设置检查时间间隔以查看小时是否为8(早上8点)。

这将检查每分钟(60000毫秒),看它是否是八点钟:

window.setInterval(function(){ // Set interval for checking 
    var date = new Date(); // Create a Date object to find out what time it is 
    if(date.getHours() === 8 && date.getMinutes() === 0){ // Check the time 
     // Do stuff 
    } 
}, 60000); // Repeat every 60000 milliseconds (1 minute) 

它不会在正好 8点执行(除非你开始运行这个权利因为它每分钟检查一次。您可以尽可能减少间隔,因为您希望增加支票的准确性,但这是过分的原因:它会每分钟检查每小时每天看它是否是8点。

检查的强度是由于JavaScript的本质:这类事情有更好的语言和框架。由于JavaScript在加载时在网页上运行,因此它并不意味着要处理持久的扩展任务。

也意识到这需要它正在执行的网页开放。也就是说,如果页面没有打开并且每分钟检查,则无法在每天早上8点执行预定操作。

你说你已经每五秒刷新一次页面:如果这是真的,你根本不需要定时器。只是检查每次刷新页面时间:

var date = new Date(); // Create Date object for a reference point 
if(date.getHours() === 8 && date.getMinutes() === 0 && date.getSeconds() < 10){ // Check the time like above 
    // Do stuff 
} 

有了这个,你还必须检查秒钟,因为你刷新每五秒钟,所以你会得到重复的任务。


虽这么说,你可能想在OS X

计划任务如果你需要更多的东西与平台无关的像做this或编写的Automator工作流,我会认真考虑采取看看PythonBash


为更新,JavaScript for Automation与OS X的优胜美地介绍,这似乎提供了使用JavaScript为这样的事情的可行方法(尽管很显然你不是在同一个环境中使用它;苹果只是给你一个本地使用另一种脚本语言的界面)。

如果您使用的是OS X并且确实想使用JavaScript,我认为这是一条路。

与上面相关的发行注记似乎是本文的唯一现有文档(约优米米特发布后约2个月),但值得一读。您还可以查看标签以查看一些示例。

我也发现JXA Cookbook非常有用有帮助。

您可能需要稍微调整一下这个方法以适应您的特定情况,但我会给出一个总体概述。

  1. 在Automator中创建一个空白应用程序。
    • 打开Automator.app(它应该在您的Applications目录中)并创建一个新文档。
    • 从对话框中选择“应用程序”。 Automator new document dialog
  2. 添加JavaScript操作。
    • 下一步是实际添加将要执行的JavaScript。要做到这一点,首先在工作流中添加一个“运行JavaScript”动作。 Drag the JS file into the workflow
  3. 编写JavaScript。

    • 这是你在继续之前必须知道你想做什么的地方。根据您提供的信息,我假设您要在Safari中加载的页面上执行window.print()。你可以做到这一点(或者更一般地说,在Safari浏览器选项卡中执行任意JS)与此:

      var safari = Application('Safari'); 
      safari.doJavaScript('window.print();', { in: safari.windows[0].currentTab }); 
      
    • 您可能需要调整其windows您根据您的设置访问的。
  4. 保存应用程序。
    • 保存(File -> Save + 小号)的文件中,你可以找到(或iCloud中)的位置的应用程序。
  5. 安排它运行。
    • 打开日历(或iCal)。
    • 创建一个新事件并为其指定一个可识别的名称;然后,将时间设置为所需的运行时间(在这种情况下,上午8:00)。
    • 将活动设置为每天重复(或每周,每月等 - 但通常您希望它运行)。
    • 将警报(或警报,取决于您的版本)设置为自定义。
    • 选择“打开文件”并选择您保存的应用程序文件。
    • 选择“在事件发生时”提醒计时选项。 GIF instructions for scheduling the event

这就是它!每次将该事件设置为运行时,您在应用程序文件中编写的JavaScript代码都会运行。您应该能够返回到Automator中的文件并根据需要修改代码。

+1

@Christophe如何?如果你指的是它不会在* 8:00正好运行的事实,它将在那一分钟内的某个时刻运行。如果OP想要更加精确,他/她可以缩短间隔,但是它过于夸张。 – AstroCB

+0

注意:这将在上午8点后的60秒内触发。而且@Christophe,这个* *每天都在上午8点运行(只要页面打开),因为间隔不会被取消。 – rvighne

+0

我指的是JavaScript不会运行,除非用户在该特定时间实际打开页面。我担心OP会将客户端脚本与预定的工作混淆。 – Christophe

4

我试着给我的答复,希望它可以帮助:

function startJobAt(hh, mm, code) { 
     var interval = 0; 
     var today = new Date(); 
     var todayHH = today.getHours(); 
     var todayMM = today.getMinutes(); 
     if ((todayHH > hh) || (todayHH == hh && todayMM > mm)) { 
      var midnight = new Date(); 
      midnight.setHours(24,0,0,0); 
      interval = midnight.getTime() - today.getTime() + 
        (hh * 60 * 60 * 1000) + (mm * 60 * 1000); 
     } else { 
      interval = (hh - todayHH) * 60 * 60 * 1000 + (mm - todayMM) * 60 * 1000; 
     } 
     return setTimeout(code, interval); 
    } 

随着startJobAt你只能执行一个你想要的任务,但如果你需要重新运行你的任务就看你回忆startJobAt 。

再见

如果你需要自动打印操作,没有对话框,可以考虑使用http://jsprintsetup.mozdev.org/reference.html插件Mozilla或其他插件其他bowsers。

2

我已经写功能,其

  • 允许表达秒的延迟,new Date()格式和stringnew Date格式
  • 允许取消计时器

这里是代码:

"use strict" 
/** 
    This function postpones execution until given time. 
    @delay might be number or string or `Date` object. If number, then it delay expressed in seconds; if string, then it is parsed with new Date() syntax. Example: 
     scheduleAt(60, function() {console.log("executed"); } 
     scheduleAt("Aug 27 2014 16:00:00", function() {console.log("executed"); } 
     scheduleAt("Aug 27 2014 16:00:00 UTC", function() {console.log("executed"); } 
    @code function to be executed 
    @context @optional `this` in function `code` will evaluate to this object; by default it is `window` object; example: 
     scheduleAt(1, function(console.log(this.a);}, {a: 42}) 
    @return function which can cancel timer. Example: 
     var cancel=scheduleAt(60, function(console.log("executed.");}); 
     cancel(); 
     will never print to the console. 
*/ 

function scheduleAt(delay, code, context) { 

    //create this object only once for this function 
    scheduleAt.conv = scheduleAt.conv || { 
     'number': function numberInSecsToUnixTs(delay) { 
      return (new Date().getTime()/1000) + delay; 
     }, 
     'string': function dateTimeStrToUnixTs(datetime) { 
      return new Date(datetime).getTime()/1000; 
     }, 
     'object': function dateToUnixTs(date) { 
      return date.getTime()/1000; 
     } 
    }; 

    var delayInSec = scheduleAt.conv[typeof delay](delay) - (new Date().getTime()/1000); 

    if (delayInSec < 0) throw "Cannot execute in past"; 

    if (debug) console.log('executing in', delayInSec, new Date(new Date().getTime() + delayInSec * 1000)) 

    var id = setTimeout(
     code, 
     delayInSec * 1000 
    ); 

    //preserve as a private function variable setTimeout's id 
    return (function(id) { 
     return function() { 
      clearTimeout(id); 
     } 
    })(id); 
} 

使用硫S作为如下:

scheduleAt(2, function() { 
    console.log("Hello, this function was delayed 2s."); 
}); 

scheduleAt(
    new Date().toString().replace(/:\d{2} /, ':59 '), 
    function() { 
     console.log("Hello, this function was executed (almost) at the end of the minute.") 
    } 
); 

scheduleAt(new Date(Date.UTC(2014, 9, 31)), function() { 
    console.log('Saying in UTC time zone, we are just celebrating Helloween!'); 
}) 
+0

当然,我用http://jsbeautifier.org/格式化了代码 – test30

5
function every8am (yourcode) { 
    var now = new Date(), 
     start, 
     wait; 

    if (now.getHours() < 7) { 
     start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0, 0); 
    } else { 
     start = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 8, 0, 0, 0); 
    } 

    wait = start.getTime() - now.getTime(); 

    if(wait <= 0) { //If missed 8am before going into the setTimeout 
     console.log('Oops, missed the hour'); 
     every8am(yourcode); //Retry 
    } else { 
     setTimeout(function() { //Wait 8am 
      setInterval(function() { 
       yourcode(); 
      }, 86400000); //Every day 
     },wait); 
    } 
} 

要使用它:基本上

var yourcode = function() { 
     console.log('This will print evryday at 8am'); 
    }; 
every8am(yourcode); 

,获得现在的时间戳,今天上午8时的时间戳,如果在时间运行,或明天上午8点,然后设置一个每天24小时的间隔运行代码。您可以通过在不同的时间戳处设置变量启动来轻松更改运行时间。

我不知道怎么会做这种想法是有用的,因为其他指出的那样,你就需要有页面打开成天看到这种情况发生......

而且,由于你是刷新每5秒:

function at8am (yourcode) { 
    var now = new Date(), 
     start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0, 0); 

    if (now.getTime() >= start.getTime() - 2500 && now.getTime() < start.getTime() + 2500) { 
     yourcode(); 
    } 
} 

运行同样的方式作为every8am,它看起来的,如果是早上8点提前2.5second还是落后的,如果它运行。

0

我会建议在Web Worker概念中这样做,因为它独立于其他脚本并在不影响页面性能的情况下运行。

  1. 创建网络工作者(demo_worker.js)

    var i = 0; 
    var date = new Date(); 
    var counter = 10; 
    var myFunction = function(){ 
        i = i + 1; 
        clearInterval(interval); 
        if(date.getHours() === 8 && date.getMinutes() === 0) { 
         counter = 26280000; 
         postMessage("hello"+i); 
        }  
        interval = setInterval(myFunction, counter); 
    } 
    var interval = setInterval(myFunction, counter); 
    
  2. 使用在乌尔代码的网络工作者如下。

    var w;如果(typeof(Worker)!==“undefined”){ if(typeof(w)==“undefined”){ w = new Worker(“Demo_worker.js”); w.onmessage = function(event){ window.print(); }; } else { document.getElementById(“result”)。innerHTML =“对不起,您的浏览器不支持”; }} }

我认为这将帮助你。

相关问题