JQuery 具有 Google Apps 脚本的移动设备

JQuery Mobile with Google Apps Script

我使用 HTML服务制作了一个 Google Apps 脚本部署为独立的网络应用程序,该服务提供了一个简单的前端来将预算数据输入 Google 电子表格。我正在为某些 javascript 使用 JQuery 移动设备,并将其设计为适合移动设备的方式,因为此应用程序的主要用例是通过我的手机输入购买内容。

我的问题是,在移动浏览器上,应用程序无法正确缩放。它是浏览器的宽度,但它好像是 "zoomed out"。所有控件在移动设备上基本上无法使用。

如果脚本嵌入到 Google 个站点中,它可以正确缩放,但我宁愿能够直接查看 Web 应用程序,而不是将其嵌入到 Google 个站点中。

编辑:我的代表现在足以 post 照片,所以它们在这里(代码下方)。

编辑:我的 HTML 的开头如下。我最初在这里有 javascript 和完整的 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:

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

完整代码片段:

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

您可以通过 CSS 媒体查询确定显示的大小。例如,将此添加到您的 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;
  }
}

使用 Chrome 的设备模拟,表格看起来很不错。 (红色背景由上面 css 设置。)但是当我从我的真实 iPhone 6+ 访问该应用程序时,并非所有元素都同样缩放。 (例如提交按钮。)因此可能需要一些其他特定的 css 来进一步调整结果。

这应该会对 addmetatagname() of Class HtmlOutput 有所帮助。你应该通过代码修改meta标签。

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

这会有所帮助

我确实遇到了这个问题。我试图做的就是测试网站的一些 jQuery 移动模板,而不将它们部署到 Google App EngineGoogle Cloud Storage.

Google 云端硬盘不再让您直接提供服务 HTML,因此应用脚本是下一个最佳选择。

问题 是应用程序脚本 iframe 一切,为本应在移动设备上查看的内容创建视口问题(即使在解决 jQuery src= 需要 https 而不是 http).

解决方法是在 iframe 页面上添加一个 META 标记以及您正在提供的 HTML 标记。

无论如何,说添加 META 标签的两个答案效果很好。

如果您提供 jQuery 移动页面,此 code.gs 代码对我有用:

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

其中 test 是您的 test.html 文件。