Google App Script 中的 SpreadsheetApp 服务可以读取、创建、修改 Google Sheet。
例如下方代码,SpreadsheetApp.getActiveSpreadsheet()方法得到当前表格文件对象(Spreadsheet),currentSpreadsheet.getActiveSheet()方法得到当前工作表对象(Sheet),currentSheet.getCurrentCell()得到当前活动单元格对象(Range),再通过单元格对象的getValue方法获取到活动单元格的值。

function logCurrent() {
  let currentSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
  let currentSheet = currentSpreadsheet.getActiveSheet();
  let currentRange = currentSheet.getCurrentCell();
  console.log(currentRange.getValue());
}

由小到大,可以把 Google Sheet 分为 Range、RangeList、Sheet、Spreadsheet。

Range

Range 是 Google Sheet 里的最小元素,表示单元格的区域,可以是一个单元格或者是一组单元格
当是一个单元格时可以用getValue()方法获取单元格显示的值,返回字符串;当是一组单元格则需要用getValues()来获取值,返回一个二维数组,第一层为行,第二层为列。

如下图,data最终的值为[[1,2],[3,4]]
spreadsheetapp1.JPG

function logData() {
  let sheet = SpreadsheetApp.getActiveSheet();
  let range = sheet.getDataRange()
  let data = range.getValues();
  console.log(data);
}

- 阅读剩余部分 -

Google App Script 里的函数可以在 Google Sheet 的公式里直接调用,例如可以自定义一个DOUBLE函数,当输入公式=DOUBLE(A1)将 A1 的值乘以二倍后返回,通过自定义函数可以实现默认函数不支持的功能。
custom-function.jpg

function DOUBLE(input) {
  return input * 2;
}

在公式里使用自定义函数时,系统先会自动处理传入的值然后再作为参数传入。例如=DOUBLE(A1:B1),最终input的值会是一个二维数组[[1,2]],所以需要在函数里添加处理数组的方法。

- 阅读剩余部分 -

Google 的在线应用允许用户通过脚本(Google Apps Script)对其增加功能,以 Google Sheets 为例,我们可以增加一个菜单,加入一些本来没有的功能,如果你会 JavaScript,很容易就会上手了。
google sheets menu.png

添加脚本

通过工具栏工具-脚本编辑器来到脚本页,默认建立了一个.gs后缀名的脚本文件,并且写了一个myFunction函数。
添加一行代码Logger.log("ok");,点击运行按钮,运行完成后在查看-日志里就能看到一行输出ok
Logger.log()的功能类似 JavaScript 里的Console.log(),要注意的是,Google Apps Script 并不是支持所有的 JS API。
google sheet logger.png

- 阅读剩余部分 -

Tablesorter是一个JQuery插件,功能是对标准的table进行排序,很简单,只要一句JS代码就能实现点击表头排序的功能,但也很强大,通过设置也能实现表头锁定,Ajax加载数据,分页,主题,复杂表头,表格嵌套等等功能,官方的API头都可以给你看大😂。

简单开始

引用JS文件

<script type="text/javascript" src="jquery.min.js"></script> 
<script type="text/javascript" src="jquery.tablesorter.js"></script> 

构造标准的表格

<table id="myTable" class="tablesorter"> 
<thead> 
<tr> 
    <th>Last Name</th> 
    <th>First Name</th> 
    <th>Email</th> 
    <th>Due</th> 
    <th>Web Site</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
    <td>Smith</td> 
    <td>John</td> 
    <td>jsmith@gmail.com</td> 
    <td>$50.00</td> 
    <td>http://www.jsmith.com</td> 
</tr> 
<tr> 
    <td>Bach</td> 
    <td>Frank</td> 
    <td>fbach@yahoo.com</td> 
    <td>$50.00</td> 
    <td>http://www.frank.com</td> 
</tr> 
<tr> 
    <td>Doe</td> 
    <td>Jason</td> 
    <td>jdoe@hotmail.com</td> 
    <td>$100.00</td> 
    <td>http://www.jdoe.com</td> 
</tr> 
<tr> 
    <td>Conway</td> 
    <td>Tim</td> 
    <td>tconway@earthlink.net</td> 
    <td>$50.00</td> 
    <td>http://www.timconway.com</td> 
</tr> 
</tbody> 
</table> 

对表格应用Tablesorter

$(document).ready(function() 
    { 
        $("#myTable").tablesorter(); 
    } 
); 

到此你的表格就已经被赋予了排序功能,排序点击表头即可~
tablesorter.jpg

没看错,默认的表格就是这么丑,不过Tablesorter支持主题,往下看
引用主题css文件

<link rel="stylesheet" href="theme.dropbox.css">

注册主题

$("#myTable").tablesorter({
    theme:"dropbox"
}); 

tablesorter1.jpg

瞬间回到现代,这是个dropbox风格主题。

- 阅读剩余部分 -

两种方式语义是一样的,不过后一种属性的名称被看作字符串,可以更好的避免和 JS 里预留关键词冲突。

obj.for = "Simon"; // 语法错误,因为 for 是一个预留关键字
obj["for"] = "Simon"; // 工作正常

不过在定义属性时也最好不要用预留关键词!

今天在博客园看到的,通过反编译播放器找到解码音乐资源的地址的算法。

算法这里就不多解释了,原文有分析,这里说一下获取“加密”地址的过程:

1.进入单首歌曲介绍页,比如 http://www.xiami.com/song/1768914936 ,地址后面的数字就是歌曲的 id

2.根据 id 找到包含歌曲相关信息的 xml 文件地址,例如 http://www.xiami.com/song/playlist/id/1768914936/object_name/default/object_id/0

3.载入 xml ,获取 location 节点的内容,就是“加密”的地址

- 阅读剩余部分 -

Opera 扩展包括有“后台脚本”、“注入脚本”、“弹窗脚本”等,所谓“消息”,各脚本间的数据传递就是通过消息实现的。

Opera 扩展发送消息的方式有3种,postMessage()/broadcastMessage()/消息通道。

例如在后台脚本和注入脚本之间传递数据:

可以使用 broadcastMessage() 来发送消息。你可以在后台脚本中这样写:

opera.extension.broadcastMessage("Hello there");

- 阅读剩余部分 -