简体   繁体   English

使用Google Apps脚本的JQuery Mobile

[英]JQuery Mobile with Google Apps Script

I've made a Google Apps Script deployed as a standalone web app using HTMLService that provides a simple front end to enter budget data into a Google Spreadsheet. 我使用HTMLService将Google Apps脚本部署为独立的Web应用程序,该应用程序提供了一个简单的前端,可将预算数据输入到Google电子表格中。 I'm using JQuery Mobile for some of the javascript as well as to style it a mobile-friendly manner, as my main use case for this app is to enter purchases from my mobile. 我正在使用JQuery Mobile来获取一些javascript,并将其设置为一种适合移动设备的方式,因为我的应用程序的主要用例是从我的手机中输入购买。

My problem is that on a mobile browser, the app doesn't scale properly. 我的问题是,在移动浏览器上,该应用程序无法正常扩展。 It's the width of the browser, but it's as if it was "zoomed out". 这是浏览器的宽度,但就好像它已经“缩小”了。 All the controls become essentially unusable on mobile. 所有控件在移动设备上基本上都无法使用。

If the script is embedded in a Google Site, it scales properly, but I'd rather be able to view the web app directly, rather than embed it in Google Sites. 如果脚本嵌入在Google网站中,它可以正常扩展,但我宁愿能够直接查看该网络应用,而不是将其嵌入Google协作平台。

EDIT: My rep is high enough to post photos now, so here they are (below code). 编辑:我的代表现在足够高,可以发布照片,所以在这里(代码下面)。

EDIT: The beginning of my HTML is below. 编辑:我的HTML的开头在下面。 I originally had the javascript and the full HTML in here, and I can add snippets if needed, but I reviewed it again and don't think it's relelvant to the problem it was cluttering up the question, so I removed it. 我最初在这里有javascript和完整的HTML,如果需要的话我可以添加片段,但是我再次对它进行了审核,并且认为它不会解决问题,因为我把它删除了。

HTML: HTML:

<!DOCTYPE html>

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css">
<?!= include('javascript'); ?>

<div data-role="page" data-theme="a" id="main">
        <div data-role="content">
            <form id="myForm">
...

Code.gs: Code.gs:

function doGet() {
    return HtmlService.createTemplateFromFile('index').evaluate()
    .setSandboxMode(HtmlService.SandboxMode.IFRAME).setTitle('Budget Entry');
}

直接访问(左)和嵌入在Google协作平台(右)。

Snippet with full code: 带完整代码的代码段:

 //<script> function formSuccess() { var dateSelect = document.getElementById("date"); var dateSelected = dateSelect.options[dateSelect.selectedIndex].text; var catSelect = document.getElementById("category"); var catSelected = catSelect.options[catSelect.selectedIndex].text; var amountEntered = document.getElementById("amount").value; var noteEntered = document.getElementById("note").value; var successMsg = 'Date: ' + dateSelected + '<br>Category: ' + catSelected + '<br>Amount: $' + amountEntered + '<br>Note: ' + noteEntered; $('#dialogMain').html(successMsg); $.mobile.silentScroll(0); $.mobile.changePage( "#dialog", { role: "dialog" } ); requestCategoryInfo(document.getElementById("status")); document.getElementById("amount").value = ''; document.getElementById("note").value = ''; } function submitForm() { if (document.getElementById('amount').value.length == 0) { alert('Please enter an amount.'); return; } $.mobile.loading( 'show' ); $('#status').html(''); google.script.run .withSuccessHandler(formSuccess) .processForm(document.getElementById('myForm')); } function loadUI() { $.mobile.loading( 'show' ); loadDateSelect(); google.script.run.withSuccessHandler(loadCategoryNamesAndValues).withFailureHandler(sendLog) .getCategoryNamesAndValues(); $.mobile.loading( 'hide' ); } function loadDateSelect(){ var d = new Date(); var month = d.getMonth()+1; var today = d.getDate(); var daysInAMonth = [0,31,28,31,30,31,30,31,31,30,31,30,31]; for (var n=1; n <= daysInAMonth[month]; n++) { var option = $("<option>").attr('value',n).text(month+"/"+n); $('#date').append(option); } $('#date').val(today); $('#date').selectmenu('refresh', true); } function loadCategoryNamesAndValues(catNamesAndValues){ var namesAndValues = catNamesAndValues; var optionHTML = ''; var currentGroup = ''; var catName = ''; var catID = ''; for (var i=0; i<namesAndValues.length; i++) { catName = namesAndValues[i][0]; catID = namesAndValues[i][1]; if (catID.toString() == "Group"){ // Handle Group Name if (currentGroup.length > 0) { // close previous optgroup tag optionHTML += "</optGroup>"; } // Open optGroup currentGroup = catName; optionHTML += "<optGroup label='" + currentGroup + "'>"; } else if (isNaN(parseInt(catID)) || parseInt(catID) == 0){ //Do Nothing } else { // Create Option HTML as: <option value=namesAndValues[i][1]>namesAndValues[i][0]</option> optionHTML += "<option value='" + catID + "'>" + catName + "</option>"; } } // Close current OptGroup optionHTML += "</optGroup>" document.getElementById('category').innerHTML = optionHTML; $('#category').selectmenu('refresh', true); } function categoryChanged() { setStatus(''); requestCategoryInfo(document.getElementById('status')); } function requestCategoryInfo(container) { $.mobile.loading( 'show' ); google.script.run .withSuccessHandler(displayCategoryInfo) .withFailureHandler(sendLog) .withUserObject(container) .getCategoryInfo(document.getElementById('category').value); } function displayCategoryInfo(categoryInfo, container){ var spentStr = 'Spent $' + categoryInfo.actual.toFixed(2) + ' of $' + categoryInfo.budgeted.toFixed(2); var remainingStr = 'Remaining: $' + categoryInfo.remaining.toFixed(2); var statusDiv = container; if (statusDiv.innerHTML.length > 0){ statusDiv.innerHTML += '<br>'}; statusDiv.innerHTML += spentStr + '<br>' + remainingStr; if (String(categoryInfo.fundAmount).length > 0) { var fundAmountStr = ''; if (categoryInfo.remaining < 0) { fundAmountStr = (categoryInfo.fundAmount + categoryInfo.remaining).toFixed(2); } else { fundAmountStr = categoryInfo.fundAmount.toFixed(2); } statusDiv.innerHTML += '<br>Fund: $' + fundAmountStr; } $.mobile.loading( 'hide' ); } function setStatus(html){ document.getElementById('status').innerHTML = html; } function appendStatus(html){ setStatus(document.getElementById('status').innerHTML + '<br>' + html); } function sendLog(){ google.script.run.sendLog(); } //</script> 
 <!DOCTYPE html> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"></script> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css"> <?!= include('javascript'); ?> <div data-role="page" data-theme="a" id="main"> <div data-role="content"> <form id="myForm"> <div>Date</div> <div><select name="date" id="date"></select></div> <div>Category</div> <div><select name=category id="category" onchange="categoryChanged()" required></select></div> <div>Amount</div> <div><input type="text" name="amount" id="amount" required></div> <div>Note</div> <div><input type="text" name="note" id="note"></div> <div><input type="button" id="submit" value="Submit" onclick="submitForm()"/></div> </form> <!--<a href="#dialog" data-role="button" data-rel="dialog" data-transition="pop">Dialog</a>--> </div><!-- /content --> <div data-role="footer"> <div id="status"></div> </div><!-- /footer --> </div><!-- /page --> <div data-role="page" id="dialog" data-close-btn="none"> <div data-role="header"> <h1 id="dialogHeading">Success!</h1> </div> <div data-role="main" class="ui-content" id="dialogMain"> <p>Text goes here.</p> </div> <div class="ui-grid-b"> <div class="ui-block-a"></div> <div class="ui-block-b"><a href="#main" data-role="button" data-icon="check">OK</a></div> <div class="ui-block-c"></div> </div><!-- /grid-a --> <!--><div data-role="footer"></div>--> </div> <script type="text/javascript"> $(loadUI); </script> 

var output = HtmlService.createHtmlOutput('<b>Hello, world!</b>');
output.addMetaTag('viewport', 'width=device-width, initial-scale=1');

this will help 这会有所帮助

You can determine the size of the display via CSS Media Queries. 您可以通过CSS Media Queries确定显示的大小。 For example, adding this to your CSS causes the form to display differently depending on the device's screen size: 例如,将其添加到CSS会导致表单以不同的方式显示,具体取决于设备的屏幕大小:

@media only screen and (min-device-width: 413px) and (max-device-width: 415px) { /* iPhone 6+ */
  #main, #dialog {
   zoom: 3;
   background: red;
  }
}

@media only screen and (min-device-width: 374px) and (max-device-width: 376px) { /* iPhone6 Styles */
  #main, #dialog  {
   transform: scale(2);
    background: blue;
  }
}

@media only screen and (min-device-width: 359px) and (max-device-width: 361px) { /* iPhone6+ Alt Styles */
  #main, #dialog  {
   transform: scale(2);
    background: green;
  }
}

@media only screen and (min-device-width: 319px) and (max-device-width: 321px) { /* iPhone5 or less Styles */
  #main, #dialog  {
   transform: scale(2);
    background: grey;
  }
}

Using Chrome's device emulation, the form looked pretty good. 使用Chrome的设备模拟,表单看起来非常好。 (The red background is set by the above css.) But when I accessed the app from my real iPhone 6+, not all elements zoomed equally. (红色背景由上面的CSS设置。)但是当我从真正的iPhone 6+访问应用程序时,并非所有元素都放大了。 (Submit button for example.) So there is likely some other specific css needed to further tailor the result. (例如,提交按钮。)因此,可能需要一些其他特定的CSS来进一步定制结果。

截图 截图

I had this exact problem. 我有这个确切的问题。 All I was trying to do is test some jQuery mobile templates for a website without deploying them to either Google App Engine or Google Cloud Storage . 我所要做的就是为网站测试一些jQuery移动模板,而不是将它们部署到Google App EngineGoogle Cloud Storage

Google Drive no longer lets you serve HTML directly, so the app script is the next best option. Google云端硬盘不再允许您直接投放HTML ,因此应用脚本是下一个最佳选择。

The problem is that app scripts iframe everything, creating viewport problems for things meant to be viewed on mobile (even after fixing the problem where jQuery src= need to be https instead of http ). 问题是应用程序脚本iframe的所有内容,为想要在移动设备上查看的内容创建视口问题(即使在解决了jQuery src=需要https而不是http )。

The fix is to have a META tag on the iframe page in addition to the HTML you're serving. 解决方法是在iframe页面上添加META标记以及您正在提供的HTML

Anyway, the two answers that say to add a META tag worked great. 无论如何,添加META标签的两个答案效果很好。

If you are serving a jQuery mobile page, this code.gs code worked for me: 如果你正在提供jQuery移动页面,这个code.gs代码对我code.gs

function doGet() {
  var output = HtmlService.createHtmlOutputFromFile('test');
  output.addMetaTag('viewport', 'width=device-width, initial-scale=1');
  return output;
}

Where test is your test.html file. test是你的test.html文件。

This should help addmetatagname() of Class HtmlOutput . 这应该有助于Class HtmlOutput的addmetatagname() You should modify the meta tag through code. 您应该通过代码修改元标记。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM