-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathoverview.html
782 lines (687 loc) · 32.9 KB
/
overview.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="stable/static/css/site.css" rel="stylesheet" type="text/css">
<link href="stable/static/css/print.css" rel="stylesheet" type="text/css" media="print">
<link href="stable/static/css/prettify.css" rel="stylesheet" type="text/css">
<link href="//www.google.com/images/icons/product/chrome-16.png" rel="icon" type="image/ico">
<title>概述 - chrome插件中文开发文档(非官方)</title>
</head>
<body>
<a id="top"></a>
<div id="header">{Header content}</div>
<a id="gc-topnav-anchor"></a>
<div id="gc-topnav">
<h1>chrome插件中文开发文档(非官方)</h1>
<ul id="home" class="gc-topnav-tabs">
<li id="home_link">
<a href="index.html" title="Google Chrome Extensions home page"><div>主页</div></a>
</li>
<li id="docs_link">
<a href="docs.html" title="Official Google Chrome Extensions documentation"><div>文档</div></a>
</li>
<li id="faq_link">
<a href="faq.html" title="Answers to frequently asked questions about Google Chrome Extensions"><div>常见问题</div></a>
</li>
<li id="samples_link">
<a href="samples.html" title="Sample Extensions (with source code)"><div>示例</div></a>
</li>
<li id="group_link">
<a href="http://groups.google.com/a/chromium.org/group/chromium-extensions" title="Google Chrome Extensions developer forum"><div>google群组(英文)</div></a>
</li>
<li id="so_link">
<a href="http://stackoverflow.com/questions/tagged/google-chrome-extension" title="[google-chrome-extension] tag on Stack Overflow"><div>还有问题?(英文)</div></a>
</li>
</ul>
</div>
<div id="gc-container">
<div id="gc-sidebar">
<ul
class="level1 ">
<li class="level2">
<a href="getstarted.html" class="level2 ">入门</a>
</li>
<li class="level2">
<a href="overview.html" class="level2 ">概述</a>
</li>
<li class="level2">
<a href="whats_new.html" class="level2 ">新功能</a>
</li>
<li class="level2">
<a href="devguide.html" class="level2 ">开发者指南</a>
<ul
class="level2 ">
<li class="level3">
<a class="button level3">
<span class="level3">用户界面</span>
<div class="toggleIndicator level3"></div>
</a>
<ul toggleable
class="level3 hidden">
<li class="level4">
<a href="browserAction.html" class="level4 ">浏览器按钮</a>
</li>
<li class="level4">
<a href="contextMenus.html" class="level4 ">右键菜单</a>
</li>
<li class="level4">
<a href="notifications.html" class="level4 ">桌面通知</a>
</li>
<li class="level4">
<a href="omnibox.html" class="level4 ">多功能地址栏</a>
</li>
<li class="level4">
<a href="options.html" class="level4 ">选项页面</a>
</li>
<li class="level4">
<a href="override.html" class="level4 ">代替页面</a>
</li>
<li class="level4">
<a href="pageAction.html" class="level4 ">页面按钮</a>
</li>
</ul>
</li>
<li class="level3">
<a class="button level3">
<span class="level3">浏览器交互</span>
<div class="toggleIndicator level3"></div>
</a>
<ul toggleable
class="level3 hidden">
<li class="level4">
<a href="bookmarks.html" class="level4 ">书签</a>
</li>
<li class="level4">
<a href="cookies.html" class="level4 ">Cookies</a>
</li>
<li class="level4">
<a href="devtools.html" class="level4 ">开发人员工具</a>
</li>
<li class="level4">
<a href="events.html" class="level4 ">事件</a>
</li>
<li class="level4">
<a href="history.html" class="level4 ">历史记录</a>
</li>
<li class="level4">
<a href="management.html" class="level4 ">管理</a>
</li>
<li class="level4">
<a href="tabs.html" class="level4 ">标签页</a>
</li>
<li class="level4">
<a href="windows.html" class="level4 ">窗口</a>
</li>
</ul>
</li>
<li class="level3">
<a class="button level3">
<span class="level3">实现</span>
<div class="toggleIndicator level3"></div>
</a>
<ul toggleable
class="level3 hidden">
<li class="level4">
<a href="a11y.html" class="level4 ">辅助功能</a>
</li>
<li class="level4">
<a href="event_pages.html" class="level4 ">事件页面</a>
</li>
<li class="level4">
<a href="contentSecurityPolicy.html" class="level4 ">内容安全策略(CSP)</a>
</li>
<li class="level4">
<a href="content_scripts.html" class="level4 ">内容脚本</a>
</li>
<li class="level4">
<a href="xhr.html" class="level4 ">跨站XMLHttpRequest</a>
</li>
<li class="level4">
<a href="i18n.html" class="level4 ">国际化</a>
</li>
<li class="level4">
<a href="messaging.html" class="level4 ">消息传递</a>
</li>
<li class="level4">
<a href="permissions.html" class="level4 ">可选权限</a>
</li>
<li class="level4">
<a href="npapi.html" class="level4 ">NPAPI插件</a>
</li>
</ul>
</li>
<li class="level3">
<a class="button level3">
<span class="level3">完成</span>
<div class="toggleIndicator level3"></div>
</a>
<ul toggleable
class="level3 hidden">
<li class="level4">
<a href="hosting.html" class="level4 ">托管</a>
</li>
<li class="level4">
<a href="external_extensions.html" class="level4 ">其他部署方案</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="level2">
<a href="tutorials.html" class="level2 ">教程</a>
<ul
class="level2 ">
<li class="level3">
<a href="tut_migration_to_manifest_v2.html" class="level3 ">清单文件V2</a>
</li>
<li class="level3">
<a href="tut_debugging.html" class="level3 ">调试</a>
</li>
<li class="level3">
<a href="tut_analytics.html" class="level3 ">Google Analytics(分析)</a>
</li>
<li class="level3">
<a href="tut_oauth.html" class="level3 ">OAuth</a>
</li>
</ul>
</li>
<li class="level2">
<span class="level2">参考</span>
<ul
class="level2 ">
<li class="level3">
<a class="button level3">
<span class="level3">格式</span>
<div class="toggleIndicator level3"></div>
</a>
<ul toggleable
class="level3 hidden">
<li class="level4">
<a href="manifest.html" class="level4 ">清单文件</a>
</li>
<li class="level4">
<a href="match_patterns.html" class="level4 ">匹配表达式</a>
</li>
</ul>
</li>
<li class="level3">
<a href="permission_warnings.html" class="level3 ">权限警告</a>
</li>
<li class="level3">
<a href="api_index.html" class="level3 ">chrome.* APIs</a>
</li>
<li class="level3">
<a href="api_other.html" class="level3 ">其他APIs</a>
</li>
</ul>
</li>
<li class="level2">
<span class="level2">更多</span>
<ul
class="level2 ">
<li class="level3">
<a href="http://code.google.com/chrome/webstore/docs/index.html" class="level3 ">chrome商店</a>
</li>
<li class="level3">
<a href="http://code.google.com/chrome/apps/docs/developers_guide.html" class="level3 ">托管应用程序</a>
</li>
<li class="level3">
<a href="themes.html" class="level3 ">主题</a>
</li>
</ul>
</li>
</ul>
</div>
<div id="gc-pagecontent">
<h1 class="page_title">概述</h1>
<div id="toc">
<h2>内容</h2>
<ol>
<li>
<a href=#what>基础</a>
<ol>
<li><a href=#extension-ui>扩展程序的用户界面</a></li>
</ol>
</li>
<li>
<a href=#files>文件</a>
<ol>
<li><a href=#relative-urls>引用文件</a></li><li><a href=#manifest>清单文件</a></li>
</ol>
</li>
<li>
<a href=#arch>架构</a>
<ol>
<li><a href=#background_page>后台页面</a></li><li><a href=#pages>用户界面页面</a></li><li><a href=#contentScripts>内容脚本</a></li>
</ol>
</li>
<li>
<a href=#apis> 使用chrome.* API </a>
<ol>
<li><a href=#sync> 异步方法与同步方法的区别 </a></li><li><a href=#sync-example> 例子:使用回调函数 </a></li><li><a href=#chrome-more> 更多细节 </a></li>
</ol>
</li>
<li>
<a href=#pageComm>页面间的通信 </a>
</li>
<li>
<a href=#incognito> 保存数据和隐身模式 </a>
</li>
<li>
<a href=#now-what> 现在做什么呢? </a>
</li>
</ol>
</div>
<p>
当您看完该页面以及
<a href="getstarted.html">入门</a> 教程后,您已经准备好开始编写扩展程序和打包应用程序了。
</p>
<h2 id="what">基础</h2>
<p>
扩展程序由一些文件—HTML、CSS、JavaScript、图片以及其它任何您需要的文件—
为Google Chrome浏览器增加功能
扩展程序本质上是网页,它们可以利用
<a href="api_other.html">浏览器为网页提供的所有API</a>,
例如XMLHttpRequest、JSON、HTML5等等。
</p>
<p>
扩展程序可以通过
<a href="content_scripts.html">内容脚本</a> or
<a href="xhr.html">跨站XML请求</a>.
与网页或者服务器交互,扩展程序也可以以编程方式与浏览器功能交互,例如
<a href="bookmarks.html">书签</a>
和 <a href="tabs.html">标签页</a>.
</p>
<h3 id="extension-ui">扩展程序的用户界面</h3>
<p>
许多扩展程序—但不包括打包应用程序—以
<a href="browserAction.html">浏览器按钮</a>
或<a href="pageAction.html">页面按钮</a>.
的形式向Google Chrome浏览器增加用户界面,每个扩展程序最多能有一个浏览器按钮或页面按钮。当扩展程序与大部分网页相关时选择使用
<b>浏览器按钮</b> ,当扩展程序的图标显示还是消失取决于具体网页时选择使用
<b>页面按钮</b>。
</p>
<table class="columns">
<tr>
<td width="33%">
<img src="stable/static/images/overview/browser-action.png"
width="147" height="100"
alt="screenshot" />
</td>
<td width="33%">
<img src="stable/static/images/overview/page-action.png"
width="147" height="100"
alt="screenshot" />
</td>
<td>
<img src="stable/static/images/overview/browser-action-with-popup.png"
width="147" height="100"
alt="screenshot" />
</td>
</tr>
<tr>
<td>
这一 <a href="samples.html#gmail">邮件扩展程序</a>
使用 <em>浏览器按钮</em>
(工具栏中的图标).
</td>
<td>
这一 <a href="samples.html#mappy">地图扩展程序</a>
使用 <em>页面按钮</em>
(地址栏中的图标)
以及 <em>内容脚本</em>
(插入网页的代码).
</td>
<td>
单击时弹出内容 <em>弹出内容</em>是这一
<a href="samples.html#news">新闻扩展程序</a>
的特色。
</td>
</tr>
</table>
<p>
扩展程序(以及打包应用程序)也可以以其它形式呈现用户界面,例如在Chrome浏览器的右键菜单中添加内容,提供选项页面,或者利用内容脚本更改页面的显示方式。有关完整的扩展程序功能以及每一种功能的实现细节,请参见
<a href="devguide.html">开发者指南</a>
</p>
<h2 id="files">文件</h2>
<p>
每一个扩展程序包含以下文件:
</p>
<ul>
<li>一个<b>清单文件</b></li>
<li>一个或多个<b>HTML文件</b> (除非扩展程序是一个主题背景)</li>
<li><em>可选:</em>一个或多个<b>JavaScript文件</b></li>
<li><em>可选:</em> 您的扩展程序需要的任何其它文件,例如图片</li>
</ul>
<p>
当您编写您的扩展程序时,您将所有这些文件放在一个文件夹中。当您发布您的扩展程序时,该文件夹的内容将被压缩成一个特殊的ZIP文件,以
<code>.crx</code> 为后缀
如果您通过
<a href="https://chrome.google.com/webstore/developer/dashboard">Chrome开发者信息中心</a>,
上传您的扩展,该
<code>.crx</code>文件是自动为您创建的。
有关发布扩展的细节,参见<a href="hosting.html">托管</a>.
</p>
<h3 id="relative-urls">引用文件</h3>
<p>
您可以在扩展程序中放置任何您需要的文件,但是您如何使用它们呢?通常,您可以通过相对URL引用文件,就像在普通的HTML页面中那样。下面是一个例子,引用位于子文件夹
<code>images</code>中名为
<code>myimage.png</code>
的文件。
</p>
<pre>
<img <b>src="images/myimage.png"</b>>
</pre>
<p>
您使用Google Chrome浏览器的调试器时可能会发现,扩展程序中的每一个文件也可以通过绝对URL访问,就像这样:
</p>
<blockquote>
<b>chrome-extension://</b><em><扩展程序唯一标识符></em><b>/</b><em><文件路径></em>
</blockquote>
<p>
在这一URL中, <em><扩展程序唯一标识符></em>是扩展程序系统为每一个扩展程序生成的唯一标识符,您可以进入
<b>chrome://extensions</b>查看您载入的所有扩展的唯一标识符。
<em><文件路径></em> 是扩展程序的主目录下的文件位置,与相对URL相同。
</p>
<p>
当您编写扩展程序时(打包之前),扩展程序唯一标识符可以更改。特别地,如果您从另一个目录载入未打包的扩展程序,它的唯一标识符会改变,当您打包扩展程序时会再次改变。如果您的扩展程序代码需要指定扩展程序中某个文件的完整路径,您可以使用
<code>@@extension_id</code>这一
<a href="i18n.html#overview-predefined">预定义消息</a>
,避免开发过程中硬编码唯一标识符。
</p>
<p>
当您打包扩展程序时(典型情况下,通过信息中心上传),该扩展程序将会获得一个永久的唯一标识符,即使您更新了这一扩展程序仍然保持不变。一旦扩展程序唯一标识符变成永久的了,您就可以将所有
的<code>@@extension_id</code>修改为真正的唯一标识符。
</p>
<h3 id="manifest">清单文件</h3>
<p>
清单文件,名为<code>manifest.json</code>,
提供有关扩展程序的各种信息,例如最重要的文件和扩展程序可能具有的能力。以下是一个典型的清单文件,用于一个浏览器按钮,它将会访问来自google.com的信息:
</p>
<pre>
{
"name": "我的扩展程序",
"version": "2.1",
"description": "从Google获得信息。",
"icons": { "128": "icon_128.png" },
"background": {
"persistent": false,
"scripts": ["bg.js"]
},
"permissions": ["http://*.google.com/", "https://*.google.com/"],
"browser_action": {
"default_title": "",
"default_icon": "icon_19.png",
"default_popup": "popup.html"
}
}</pre>
<p>
有关更多细节,请参见
<a href="manifest.html">清单文件</a>.
</p>
<h2 id="arch">架构</h2>
<p>
许多扩展程序有一个<em>后台页面</em>,
它是一个包含扩展程序主要逻辑的不可见页面。扩展程序也可以包含其它页面,展现扩展程序的用户界面。如果扩展程序需要与用户载入的网页交互(相对于包含在扩展程序中的页面),扩展程序必须使用内容脚本
</p>
<h3 id="background_page">后台页面</h3>
<p>
下图所示的浏览器至少安装了两个扩展程序:一个浏览器按钮(黄色图标)和一个页面按钮(蓝色图标)。浏览器按钮和页面按钮都有后台页面。下图显示了浏览器按钮的后台页面,由
<code>background.html</code>
定义,并且包含在这两个窗口中控制浏览器按钮的JavaScript代码。
</p>
<img src="stable/static/images/overview/arch-1.gif"
width="232" height="168"
alt="Two windows and a box representing a background page (background.html). One window has a yellow icon; the other has both a yellow icon and a blue icon. The yellow icons are connected to the background page." />
<p>
后台页面分两种:
<a href="background_pages.html">持久运行的后台页面</a>,
与<a href="event_pages.html">事件页面</a>。
正如其名字所说,持续运行的后台页面保持打开状态;事件页面根据需要打开与关闭。除非您绝对需要您的后台页面一直运行,请首选事件页面。
</p>
<!-- PENDING: Perhaps show a picture of many background page processes.
This could build on a figure that shows the process architecture. -->
<p>
有关更多详情,请参见<a href="event_pages.html">事件页面</a>
与<a href="background_pages.html">后台页面</a>
。
</p>
<h3 id="pages">用户界面页面</h3>
<p>
扩展程序可以包含普通的HTML页面,用来显示扩展程序的用户界面。例如,浏览器按钮可以包含弹出内容,通过HTML文件实现。任何一个扩展程序都可以有选项页面,让用户自定义扩展程序的工作方式。另外一种特殊页面是替代页面。最后,您可以使用
<a href="tabs.html#method-create">chrome.tabs.create()</a>
或<code>window.open()</code>
来显示扩展程序中的任何其它HTML文件。
</p>
<p>
扩展程序中的HTML页面可以互相访问其它页面的全部DOM,并且可以互相调用函数。
</p>
<!-- PENDING: Change the following example and figure
to use something that's not a popup?
(It might lead people to think that popups need background pages.) -->
<p>
下图显示了浏览器按钮弹出内容的架构。弹出内容是由一个HTML文件
(<code>popup.html</code>).
定义的网页,该扩展程序也正好有一个后台页面
(<code>background.html</code>)。
弹出窗口不用重复后台页面中的代码,因为弹出窗口可以调用后台页面上的函数。
</p>
<img src="stable/static/images/overview/arch-2.gif"
width="256" height="168"
alt="A browser window containing a browser action that's displaying a popup. The popup's HTML file (popup.html) can communicate with the extension's background page (background.html)." />
<p>
有关更多细节,请参见<a href="browserAction.html">浏览器按钮</a>,
<a href="options.html">选项</a>,
<a href="override.html">替代页面</a>,
和<a href="#pageComm">页面间通信</a>这些部分。
</p>
<h3 id="contentScripts">内容脚本</h3>
<p>
如果您的扩展程序需要与网页交互,您就需要使用<em>内容脚本</em>。
内容脚本是一些JavaScript代码,它们在浏览器中已载入页面的上下文中执行。您应该将内容脚本视为已载入页面的一部分,而不是打包在一起的扩展程序
(<em>它所属的扩展程序</em>).的一部分。
</p>
<!-- [PENDING: Consider explaining that the reason content scripts are separated from the extension is due to chrome's multiprocess design. Something like:
Each extension runs in its own process.
To have rich interaction with a web page, however,
the extension must be able to
run some code in the web page's process.
Extensions accomplish this with content scripts.]
-->
<p>
内容脚本可以读取浏览器访问的网页的细节,并且可以修改页面。在下图中,内容脚本可以读取并且修改显示的网页的DOM。然而,它不能修改所属扩展程序的后台页面的DOM。
</p>
<img src="stable/static/images/overview/arch-3.gif"
width="238" height="169"
alt="A browser window with a browser action (controlled by background.html) and a content script (controlled by contentscript.js)." />
<p>
内容脚本并不是完全与所属扩展程序隔离的。内容脚本可以与所属扩展程序交换消息,如下图箭头所示。例如,每当在浏览器页面中发现RSS供稿时,内容脚本可以发送消息,反过来后台页面也可以发送消息要求内容脚本更改浏览器页面的外观。
</p>
<img src="stable/static/images/overview/arch-cs.gif"
width="238" height="194"
alt="Like the previous figure, but showing more of the parent extension's files, as well as a communication path between the content script and the parent extension." />
<p>
有关更多信息,请参见<a href="content_scripts.html">内容脚本</a>。
</p>
<h2 id="apis"> 使用chrome.* API </h2>
<p>
扩展程序除了能够使用网页和应用程序可以使用的所有API外,还能使用仅用于Chrome浏览器的API(通常称为
<em>chrome.* APIs</em>)
来更好地与浏览器集成。例如,任何扩展程序或网上应用程序可以使用标准的
<code>window.open()</code>方法来打开一个网页,但是如果您想指定网页应该显示在哪个窗口中,您的扩展程序就可以使用仅用于Chrome浏览器的
<a href="tabs.html#method-create">chrome.tabs.create()</a>
方法。
</p>
<h3 id="sync"> 异步方法与同步方法的区别 </h3>
<p>
大部分chrome.* API的方法都是<b>异步的</b>:
它们不等待操作完成就立即返回。如果您需要知道操作结果,您可以向方法传递一个回调函数,回调函数将稍后执行(可能
<em>很久</em> 之后),
在方法返回后的某个时刻。下面是一个异步方法签名的例子:
</p>
<p>
<code>
chrome.tabs.create(object <em>createProperties</em>, function <em>callback</em>)
</code>
</p>
<p>
少数chrome.*方法是<b>同步的</b>。
同步的方法没有回调参数,因为它们只有当所有操作完成后才返回。通常,同步方法有返回值类型。考虑
<a href="runtime.html#method-getURL">chrome.runtime.getURL()</a>方法:
</p>
<p>
<code>
string chrome.runtime.getURL()
</code>
</p>
<p>
该方法没有回调参数,但是有返回值类型<code>string</code>
,因为它同步地返回URL,不进行任何其它异步操作。
</p>
<h3 id="sync-example">例子:使用回调函数</h3>
<p>
假设您想在用户当前选定的标签页中打开新的页面。要想这么做,您首先需要获得当前标签页的唯一标识符(使用
<a href="tabs.html#method-getSelected">chrome.tabs.getSelected()</a>)
,然后使该标签转到指定的新的URL(使用
<a href="tabs.html#method-update">chrome.tabs.update()</a>)。
</p>
<p>
假如<code>getSelected()</code>是同步的,您可能会写这样的代码:
</p>
<pre>
<b>//以下代码不能正常工作</b>
<span class="linenumber">1: </span>var tab = chrome.tabs.getSelected(null); <b>//错误!!!</b>
<span class="linenumber">2: </span>chrome.tabs.update(tab.id, {url:newUrl});
<span class="linenumber">3: </span>someOtherFunction();
</pre>
<p>
这样的方法不行,因为<code>getSelected()</code> 是异步的。
它不等待操作完成就返回了,并且它事实上都不返回任何值(尽管有些异步方法会返回信息)。您可以通过它签名中的<em>callback</em>参数看出
<code>getSelected()</code>是异步的:
<p>
<code>
chrome.tabs.getSelected(integer <em>windowId</em>, function <em>callback</em>)
</code>
</p>
<p>
要改正上面的代码,您必须使用那个回调参数。以下代码显示如何定义一个回调函数,从
<code>getSelected()</code>
获得结果(通过名为<code>tab</code>的参数)
并调用<code>update()</code>。
</p>
<pre>
<b>//以下代码可以正常工作</b>
<span class="linenumber">1: </span>chrome.tabs.getSelected(null, <b>function(tab) {</b>
<span class="linenumber">2: </span> chrome.tabs.update(tab.id, {url:newUrl});
<span class="linenumber">3: </span><b>}</b>);
<span class="linenumber">4: </span>someOtherFunction();
</pre>
<p>
在这一例子中,以上几行是按照这样的顺序执行的:1、4、2。只有在有关当前选定标签的信息可用后,即
<code>getSelected</code>返回后的某一时刻,才调用在
<code>getSelected()</code>中指定的回调函数(并且执行第二行)。尽管
<code>update()</code>是异步的,这一例子没有使用回调参数,因为我们对于调用的结果并不感兴趣。
</p>
<h3 id="chrome-more"> 更多细节</h3>
<p>
有关更多信息,请参见
<a href="api_index.html">chrome.* API 文档</a>
并观看以下视频(英文):
</p>
<p>
<iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/bmxr75CV36A?rel=0" frameborder="0" allowfullscreen></iframe>
</p>
<h2 id="pageComm">页面间的通信</h2>
<p>
扩展程序中的HTML页面通常需要通信。因为一个扩展程序的所有页面在同一个进程中的同一个线程上执行,页面可以直接互相调用函数。
</p>
<p>
要获得扩展程序中的页面,使用
<a href="extension.html"><code>chrome.extension</code></a>
方法,例如
<code>getViews()</code>和
<code>getBackgroundPage()</code>
。一旦一个页面引用了扩展程序中的其它页面,第一个页面可以执行其它页面上的函数,并且可以操纵它们的DOM。
</p>
<h2 id="incognito"> 保存数据和隐身模式 </h2>
<p>
扩展程序可以使用HTML5<a href="http://dev.w3.org/html5/webstorage/">网页存储API</a>
(例如<code>localStorage</code>)
或者向服务器发出请求保存数据。每当您要保存任何数据前,首先考虑是否来自隐身窗口。默认情况下,扩展程序不在隐身窗口中运行,但是打包应用程序会在隐身窗口中运行。当浏览器处于隐身模式时,您需要考虑用户对您的扩展程序或打包应用程序的需求。
</p>
<p>
<em>隐身模式</em>确保不会留下任何痕迹。当处理来自隐身窗口的数据时,尽可能地遵守这一约定。例如,如果您的扩展程序通常将浏览器历史记录保存至云端,不要保存来自隐身窗口的历史记录。另一方面,您可以在任何窗口中保存您的扩展程序设置,无论隐身与否。
</p>
<p class="note">
<b>准则:</b>
如果某些数据可能显示用户在网上的访问记录或者用户所做的事情,千万不要保存来自隐身窗口的这些数据。
</p>
<p>
要确定窗口是否处于隐身模式,检查相关的
<a href="tabs.html#type-Tab">Tab</a>或
<a href="windows.html#type-Window">Window</a>对象的
<code>icognito</code>属性。例如:
</p>
<pre>
function saveTabData(tab, data) {
if (tab.incognito) {
chrome.runtime.getBackgroundPage(function(bgPage) {
bgPage[tab.url] = data; // 仅留在内存中的数据
});
} else {
localStorage[tab.url] = data; // 可以保存数据
}
}
</pre>
<h2 id="now-what"> 现在做什么呢? </h2>
<p>
现在您已经大致了解扩展程序了,您应该准备好编写您自己的扩展了。您接下来可以参考以下内容:
</p>
<ul>
<li> <a href="getstarted.html">教程:入门</a> </li>
<li> <a href="tut_debugging.html">教程:调试</a> </li>
<li> <a href="devguide.html">开发者指南</a> </li>
<li> <a href="http://dev.chromium.org/developers/design-documents/extensions/samples">示例</a> </li>
<li> <a href="http://www.youtube.com/view_play_list?p=CA101D6A85FE9D4B">视频(英文)</a>,
例如
<a href="http://www.youtube.com/watch?v=B4M_a7xejYI&feature=PlayList&p=CA101D6A85FE9D4B&index=6">扩展程序消息传递(Extension Message Passing)</a>
</li>
</ul>
</div>
</div>
</body>
<script>
window.bootstrap = {
api_names: [{"name":"alarms"},{"name":"bookmarks"},{"name":"browserAction"},{"name":"browsingData"},{"name":"commands"},{"name":"contentSettings"},{"name":"contextMenus"},{"name":"cookies"},{"name":"debugger"},{"name":"declarativeWebRequest"},{"name":"devtools.inspectedWindow"},{"name":"devtools.network"},{"name":"devtools.panels"},{"name":"downloads"},{"name":"events"},{"name":"extension"},{"name":"fileBrowserHandler"},{"name":"fontSettings"},{"name":"history"},{"name":"i18n"},{"name":"idle"},{"name":"input.ime"},{"name":"management"},{"name":"omnibox"},{"name":"pageAction"},{"name":"pageCapture"},{"name":"permissions"},{"name":"privacy"},{"name":"proxy"},{"name":"runtime"},{"name":"scriptBadge"},{"name":"storage"},{"name":"tabs"},{"name":"topSites"},{"name":"tts"},{"name":"ttsEngine"},{"name":"types"},{"name":"webNavigation"},{"name":"webRequest"},{"name":"webstore"},{"last":true,"name":"windows"}].concat(
[{"name":"experimental.bluetooth"},{"name":"experimental.devtools.audits"},{"name":"experimental.devtools.console"},{"name":"experimental.discovery"},{"name":"experimental.identity"},{"name":"experimental.infobars"},{"name":"experimental.offscreenTabs"},{"name":"experimental.processes"},{"name":"experimental.record"},{"name":"experimental.speechInput"},{"name":"experimental.systemInfo.cpu"},{"name":"experimental.systemInfo.storage"},{"last":true,"name":"experimental.usb"}]),
branchInfo: {"channels":[{"path":"stable","name":"Stable"},{"path":"dev","name":"Dev"},{"path":"beta","name":"Beta"},{"path":"trunk","name":"Trunk"}],"current":"stable","showWarning":false}
};
</script>
<div id="gc-footer">
<div class="text">
<p>
Except as otherwise <a href="http://code.google.com/policies.html#restrictions">noted</a>,
the content of this page is licensed under the <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons
Attribution 3.0 License</a>, and code samples are licensed under the
<a rel="license" href="http://code.google.com/google_bsd_license.html">BSD License</a>.
</p>
<p>
©2012 Google
</p>
<script src="stable/static/js/branch.js" type="text/javascript"></script>
<script src="stable/static/js/sidebar.js" type="text/javascript"></script>
<script src="stable/static/js/prettify.js" type="text/javascript"></script>
<script>
(function() {
// Auto syntax highlight all pre tags.
var preElements = document.getElementsByTagName('pre');
for (var i = 0; i < preElements.length; i++)
preElements[i].classList.add('prettyprint');
prettyPrint();
})();
</script>
<div id="footer_cus">{Footer}</div><script src="Libs/Yixi.js"></script><script src="http://s9.cnzz.com/stat.php?id=4928336&web_id=4928336" language="JavaScript"></script>
</div>
</div>
</html>