轮询是通过插件的用户界面中的html代码完成的,使用调用服务器端的Apps脚本函数google.script.run。
使用jQuery可以简化这一过程,我们甚至可以从简单的轮询示例jQuery的答案开始。
function doPoll(){ $.post('ajax/test.html', function(data) { alert(data); // process results here setTimeout(doPoll,5000); });}如果我们将ajax调用替换为GAS等效项,则该基本思想适用于Google Apps脚本。
这是您将在html文件中使用的poll函数的框架:
$(function() { // assign click handler(s) // Add elements that should start hidden // Start polling for updates poll(); }); function poll(interval){ interval = interval || 2000; setTimeout(function(){ google.script.run .withSuccessHandler( function(results) {$('#some-element').updateWith(results);//Setup the next poll recursivelypoll(interval); }) .withFailureHandler( function(msg, element) {showError(msg, $('#button-bar'));element.disabled = false; }) .serverFunction(); }, interval); };附加示例,文档轮询器
这是jQuery轮询技术的演示,该技术调用服务器端GoogleApps脚本函数来检测Google文档中的用户行为。它没有什么用,但是它展示了一些通常需要了解用户活动和文档状态的内容,例如,对按钮的上下文相关控制。
请遵循该指南中的说明,使用下面的代码代替快速入门中的代码。
Code.gs
function onOpen(e) { documentApp.getUi().createAddonMenu() .addItem('Start', 'showSidebar') .addToUi();}function onInstall(e) { onOpen(e);}function showSidebar() { var ui = HtmlService.createHtmlOutputFromFile('Sidebar') .setTitle('document Poller'); documentApp.getUi().showSidebar(ui);}function checkSelection() { return {isSelection : !!(documentApp.getActivedocument().getSelection()), cursorWord : getCursorWord()};}function getSelectedText() { var selection = documentApp.getActivedocument().getSelection(); if (selection) { var text = []; var elements = selection.getSelectedElements(); for (var i = 0; i < elements.length; i++) { if (elements[i].isPartial()) { var element = elements[i].getElement().asText(); var startIndex = elements[i].getStartOffset(); var endIndex = elements[i].getEndOffsetInclusive(); text.push(element.getText().substring(startIndex, endIndex + 1)); } else { var element = elements[i].getElement(); // only translate elements that can be edited as text; skip images and // other non-text elements. if (element.editAsText) { var elementText = element.asText().getText(); // This check is necessary to exclude images, which return a blank // text element. if (elementText != '') { text.push(elementText); } } } } if (text.length == 0) { throw 'Please select some text.'; } return text; } else { throw 'Please select some text.'; }}function getCursorWord() { var cursor = documentApp.getActivedocument().getCursor(); var word = "<selection>"; if (cursor) { var offset = cursor.getSurroundingTextOffset(); var text = cursor.getSurroundingText().getText(); word = getWordAt(text,offset); if (word == "") word = "<whitespace>"; } return word;}function getWordAt(str, pos) { // Perform type conversions. str = String(str); pos = Number(pos) >>> 0; // Search for the word's beginning and end. var left = str.slice(0, pos + 1).search(/S+$/), right = str.slice(pos).search(/s/); // The last word in the string is a special case. if (right < 0) { return str.slice(left); } // Return the word, using the located bounds to extract it from the string. return str.slice(left, right + pos);}Sidebar.html
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css"><!-- The CSS package above applies Google styling to buttons and other elements. --><div > <form> <div id="button-bar"> <button id="get-selection" disabled="disable">Get selection</button> </div> </form></div><div > <img alt="Add-on logo" height="27" id="logo" src="https://www.gravatar.com/avatar/adad1d8ad010a76a83574b1fff4caa46?s=128&d=identicon&r=PG"> <span >by Mogsdad, D.Bingham</span></div><script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><script> $(function() { // assign click handler(s) $('#get-selection').click(getSelection); // Add elements that should start hidden var newdiv1 = $( "<div id='cursor-word'/>" ).hide(), newdiv2 = $( "<div id='selected-text'/>" ).hide(); $('#button-bar').after( newdiv1, newdiv2 ); $('#cursor-word').html('<H2>Word at cursor:</H2><p id="cursor-word-content"></p>'); $('#selected-text').html('<H2>Selected text:</H2><p id="selected-text-content"></p>'); // Start polling for updates poll(); }); function poll(interval){ interval = interval || 2000; setTimeout(function(){ google.script.run .withSuccessHandler( function(cursor) {if (cursor.isSelection) { // Text has been selected: enable button, hide cursor word. $('#get-selection').attr('disabled', false); $('#cursor-word').hide(); // $('#selected-text').show(); // Not so fast - wait until button is clicked.}else { $('#get-selection').attr('disabled', true); $('#cursor-word').show(); $('#selected-text').hide();}$('#cursor-word-content').text(cursor.cursorWord);//Setup the next poll recursivelypoll(interval); }) .withFailureHandler( function(msg, element) {showError(msg, $('#button-bar'));element.disabled = false; }) .checkSelection(); }, interval); }; function getSelection() { this.disabled = true; $('#error').remove(); google.script.run .withSuccessHandler( function(selectedText, element) { // Show selected text $('#selected-text-content').text(selectedText); $('#selected-text').show(); element.disabled = false; }) .withFailureHandler( function(msg, element) { showError(msg, $('#button-bar')); element.disabled = false; }) .withUserObject(this) .getSelectedText(); } function showError(msg, element) { var div = $('<div id="error" >' + msg + '</div>'); $(element).after(div); }</script>Polling Interval
该setTimeout()函数接受以毫秒表示的时间间隔,但是我通过实验发现,两秒钟的响应是可以预期的最佳响应。因此,骨架poll()的默认间隔为2000毫秒。如果您的情况可以忍受更长的轮询周期之间的延迟,则可以通过onLoad调用提供更大的值poll(),例如poll(10000)10秒钟的轮询周期。



