diff options
author | Florian Merz <me@fiji-flo.de> | 2021-02-11 12:56:40 +0100 |
---|---|---|
committer | Florian Merz <me@fiji-flo.de> | 2021-02-11 12:56:40 +0100 |
commit | 310fd066e91f454b990372ffa30e803cc8120975 (patch) | |
tree | d5d900deb656a5da18e0b60d00f0db73f3a2e88e /files/zh-cn/conflicting/web/api | |
parent | 8260a606c143e6b55a467edf017a56bdcd6cba7e (diff) | |
download | translated-content-310fd066e91f454b990372ffa30e803cc8120975.tar.gz translated-content-310fd066e91f454b990372ffa30e803cc8120975.tar.bz2 translated-content-310fd066e91f454b990372ffa30e803cc8120975.zip |
unslug zh-cn: move
Diffstat (limited to 'files/zh-cn/conflicting/web/api')
43 files changed, 3938 insertions, 0 deletions
diff --git a/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html b/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html new file mode 100644 index 0000000000..3cef2b94e8 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html @@ -0,0 +1,163 @@ +--- +title: Drawing graphics with canvas +slug: Web/API/Canvas_API/Drawing_graphics_with_canvas +translation_of: Web/API/Canvas_API/Tutorial +translation_of_original: Web/API/Canvas_API/Drawing_graphics_with_canvas +--- +<div class="note"> + <p>本文大部分(但不包括关于绘制窗体部分的文档)已经被包含到更详尽的Canvas教程中,该页面因为现在已经显得多余可能会被链接到那里,但是某些信息可能仍然是十分有用的。</p> + <p> </p> +</div> +<h2 id="Introduction" name="Introduction">Introduction</h2> +<p>With <a href="/en-US/docs/Mozilla/Firefox/Releases/1.5" title="Firefox_1.5_for_developers">Firefox 1.5</a>, Firefox includes a new HTML element for programmable graphics. <code><canvas></code> is based on the <a href="http://www.whatwg.org/specs/web-apps/current-work/#the-canvas">WHATWG canvas specification</a>, which itself is based on Apple's <code><canvas></code> implemented in Safari. It can be used for rendering graphs, UI elements, and other custom graphics on the client.</p> +<p><code><canvas></code> creates a fixed size drawing surface that exposes one or more <em>rendering contexts</em>. We'll focus on the 2D rendering context. For 3D graphics, you should use the <a href="/en-US/docs/WebGL" title="https://developer.mozilla.org/en/WebGL">WebGL rendering context</a>.</p> +<h2 id="The_2D_Rendering_Context" name="The_2D_Rendering_Context">The 2D Rendering Context</h2> +<h3 id="A_Simple_Example" name="A_Simple_Example">A Simple Example</h3> +<p>To start off, here's a simple example that draws two intersecting rectangles, one of which has alpha transparency:</p> +<pre class="brush: js">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + ctx.fillStyle = "rgb(200,0,0)"; + ctx.fillRect (10, 10, 55, 50); + + ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; + ctx.fillRect (30, 30, 55, 50); +} +</pre> +<div class="hidden"> + <pre class="brush: html"><canvas id="canvas" width="120" height="120"></canvas></pre> + <pre class="brush: js">draw();</pre> +</div> +<p>{{EmbedLiveSample('A_Simple_Example','150','150','/@api/deki/files/602/=Canvas_ex1.png')}}</p> +<p>The <code>draw</code> function gets the <code>canvas</code> element, then obtains the <code>2d</code> context. The <code>ctx</code> object can then be used to actually render to the canvas. The example simply fills two rectangles, by setting fillStyle to two different colors using CSS color specifications and calling <code>fillRect</code>. The second fillStyle uses <code>rgba()</code> to specify an alpha value along with the color.</p> +<p>The <code>fillRect</code>, <code>strokeRect</code>, and <code>clearRect</code> calls render a filled, outlined, or clear rectangle. To render more complex shapes, paths are used.</p> +<h3 id="Using_Paths" name="Using_Paths">Using Paths</h3> +<p>The <code>beginPath</code> function starts a new path, and <code>moveTo</code>, <code>lineTo</code>, <code>arcTo</code>, <code>arc</code>, and similar methods are used to add segments to the path. The path can be closed using <code>closePath</code>. Once a path is created, you can use <code>fill</code> or <code>stroke</code> to render the path to the canvas.</p> +<pre class="brush: js">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + ctx.fillStyle = "red"; + + ctx.beginPath(); + ctx.moveTo(30, 30); + ctx.lineTo(150, 150); + // was: ctx.quadraticCurveTo(60, 70, 70, 150); which is wrong. + ctx.bezierCurveTo(60, 70, 60, 70, 70, 150); // <- this is right formula for the image on the right -> + ctx.lineTo(30, 30); + ctx.fill(); +} +</pre> +<div class="hidden"> + <pre class="brush: html"><canvas id="canvas" width="160" height="160"></canvas></pre> + <pre class="brush: js">draw();</pre> +</div> +<p>{{EmbedLiveSample('Using_Paths','190','190','/@api/deki/files/603/=Canvas_ex2.png')}}</p> +<p>Calling <code>fill()</code> or <code>stroke()</code> causes the current path to be used. To be filled or stroked again, the path must be recreated.</p> +<h3 id="Graphics_State" name="Graphics_State">Graphics State</h3> +<p>Attributes of the context such as <code>fillStyle</code>, <code>strokeStyle</code>, <code>lineWidth</code>, and <code>lineJoin</code> are part of the current <em>graphics state</em>. The context provides two methods, <code>save()</code> and <code>restore()</code>, that can be used to move the current state to and from the state stack.</p> +<h3 id="A_More_Complicated_Example" name="A_More_Complicated_Example">A More Complicated Example</h3> +<p>Here's a little more complicated example, that uses paths, state, and also introduces the current transformation matrix. The context methods <code>translate()</code>, <code>scale()</code>, and <code>rotate()</code> all transform the current matrix. All rendered points are first transformed by this matrix.</p> +<pre class="brush: js">function drawBowtie(ctx, fillStyle) { + + ctx.fillStyle = "rgba(200,200,200,0.3)"; + ctx.fillRect(-30, -30, 60, 60); + + ctx.fillStyle = fillStyle; + ctx.globalAlpha = 1.0; + ctx.beginPath(); + ctx.moveTo(25, 25); + ctx.lineTo(-25, -25); + ctx.lineTo(25, -25); + ctx.lineTo(-25, 25); + ctx.closePath(); + ctx.fill(); +} + +function dot(ctx) { + ctx.save(); + ctx.fillStyle = "yellow"; + ctx.fillRect(-2, -2, 4, 4); + ctx.restore(); +} + +function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + // note that all other translates are relative to this one + ctx.translate(45, 45); + + ctx.save(); + //ctx.translate(0, 0); // unnecessary + drawBowtie(ctx, "red"); + dot(ctx); + ctx.restore(); + + ctx.save(); + ctx.translate(85, 0); + ctx.rotate(45 * Math.PI / 180); + drawBowtie(ctx, "green"); + dot(ctx); + ctx.restore(); + + ctx.save(); + ctx.translate(0, 85); + ctx.rotate(135 * Math.PI / 180); + drawBowtie(ctx, "blue"); + dot(ctx); + ctx.restore(); + + ctx.save(); + ctx.translate(85, 85); + ctx.rotate(90 * Math.PI / 180); + drawBowtie(ctx, "yellow"); + dot(ctx); + ctx.restore(); +} +</pre> +<div class="hidden"> + <pre class="brush: html"><canvas id="canvas" width="185" height="185"></canvas></pre> + <pre class="brush: js">draw();</pre> +</div> +<p>{{EmbedLiveSample('A_More_Complicated_Example','215','215','/@api/deki/files/604/=Canvas_ex3.png')}}</p> +<p>This defines two methods, <code>drawBowtie</code> and <code>dot</code>, that are called 4 times. Before each call, <code>translate()</code> and <code>rotate()</code> are used to set up the current transformation matrix, which in turn positions the dot and the bowtie. <code>dot</code> renders a small black square centered at <code>(0, 0)</code>. That dot is moved around by the transformation matrix. <code>drawBowtie</code> renders a simple bowtie path using the passed-in fill style.</p> +<p>As matrix operations are cumulative, <code>save()</code> and <code>restore()</code> are used around each set of calls to restore the original canvas state. One thing to watch out for is that rotation always occurs around the current origin; thus a <code>translate() rotate() translate()</code> sequence will yield different results than a <code>translate() translate() rotate()</code> series of calls.</p> +<h2 id="Compatibility_With_Apple_.3Ccanvas.3E" name="Compatibility_With_Apple_.3Ccanvas.3E">Compatibility With Apple <canvas></h2> +<p>For the most part, <code><canvas></code> is compatible with Apple's and other implementations. There are, however, a few issues to be aware of, described here.</p> +<h3 id="Required_.3C.2Fcanvas.3E_tag" name="Required_.3C.2Fcanvas.3E_tag">Required <code></canvas></code> tag</h3> +<p>In the Apple Safari implementation, <code><canvas></code> is an element implemented in much the same way <code><img></code> is; it does not have an end tag. However, for <code><canvas></code> to have widespread use on the web, some facility for fallback content must be provided. Therefore, Mozilla's implementation has a <em>required</em> end tag.</p> +<p>If fallback content is not needed, a simple <code><canvas id="foo" ...></canvas></code> will be fully compatible with both Safari and Mozilla -- Safari will simply ignore the end tag.</p> +<p>If fallback content is desired, some CSS tricks must be employed to mask the fallback content from Safari (which should render just the canvas), and also to mask the CSS tricks themselves from IE (which should render the fallback content).</p> +<pre>canvas { + font-size: 0.00001px !ie; +}</pre> +<h2 id="Additional_Features" name="Additional_Features">Additional Features</h2> +<h3 id="Rendering_Web_Content_Into_A_Canvas" name="Rendering_Web_Content_Into_A_Canvas">Rendering Web Content Into A Canvas</h3> +<div class="note"> + This feature is only available for code running with Chrome privileges. It is not allowed in normal HTML pages. <a href="http://mxr.mozilla.org/mozilla/source/content/canvas/src/nsCanvasRenderingContext2D.cpp#2352" title="http://mxr.mozilla.org/mozilla/source/content/canvas/src/nsCanvasRenderingContext2D.cpp#2352">Read why</a>.</div> +<p>Mozilla's <code>canvas</code> is extended with the <a href="/en-US/docs/DOM/CanvasRenderingContext2D#drawWindow()" title="DOM/CanvasRenderingContext2D#drawWindow()"><code>drawWindow()</code></a> method. This method draws a snapshot of the contents of a DOM <code>window</code> into the canvas. For example,</p> +<pre class="brush: js">ctx.drawWindow(window, 0, 0, 100, 200, "rgb(255,255,255)"); +</pre> +<p>would draw the contents of the current window, in the rectangle (0,0,100,200) in pixels relative to the top-left of the viewport, on a white background, into the canvas. By specifying "rgba(255,255,255,0)" as the color, the contents would be drawn with a transparent background (which would be slower).</p> +<p>It is usually a bad idea to use any background other than pure white "rgb(255,255,255)" or transparent, as this is what all browsers do, and many websites expect that transparent parts of their interface will be drawn on white background.</p> +<p>With this method, it is possible to fill a hidden IFRAME with arbitrary content (e.g., CSS-styled HTML text, or SVG) and draw it into a canvas. It will be scaled, rotated and so on according to the current transformation.</p> +<p>Ted Mielczarek's <a href="http://ted.mielczarek.org/code/mozilla/tabpreview/">tab preview</a> extension uses this technique in chrome to provide thumbnails of web pages, and the source is available for reference.</p> +<div class="note"> + <strong>Note:</strong> Using <code>canvas.drawWindow()</code> while handling a document's <code>onload</code> event doesn't work. In Firefox 3.5 or later, you can do this in a handler for the <a href="/en-US/docs/Gecko-Specific_DOM_Events#MozAfterPaint" title="Gecko-Specific DOM Events#MozAfterPaint"><code>MozAfterPaint</code></a> event to successfully draw HTML content into a canvas on page load.</div> +<h2 id="See_also" name="See_also">See also</h2> +<ul> + <li><a href="/en-US/docs/HTML/Canvas" title="HTML/Canvas">Canvas topic page</a></li> + <li><a href="/en-US/docs/Canvas_tutorial" title="Canvas_tutorial">Canvas tutorial</a></li> + <li><a href="http://www.whatwg.org/specs/web-apps/current-work/#the-canvas">WHATWG specification</a></li> + <li><a href="http://developer.apple.com/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/Canvas.html" title="http://developer.apple.com/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/Canvas.html">Apple Canvas Documentation</a></li> + <li><a href="http://weblogs.mozillazine.org/roc/archives/2005/05/rendering_web_p.html">Rendering Web Page Thumbnails</a></li> + <li>Some <a href="/en-US/docs/tag/canvas_examples">examples</a>: + <ul> + <li><a href="http://azarask.in/projects/algorithm-ink">Algorithm Ink</a></li> + <li><a href="http://www.tapper-ware.net/canvas3d/">OBJ format 3D Renderer</a></li> + <li><a href="/en-US/docs/A_Basic_RayCaster" title="A_Basic_RayCaster">A Basic RayCaster</a></li> + <li><a href="http://awordlike.textdriven.com/">The Lightweight Visual Thesaurus</a></li> + <li><a href="http://caimansys.com/painter/">Canvas Painter</a></li> + </ul> + </li> + <li><a href="/en-US/docs/tag/canvas">And more...</a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html b/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html new file mode 100644 index 0000000000..1366009032 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html @@ -0,0 +1,107 @@ +--- +title: RandomSource +slug: Web/API/RandomSource +translation_of: Web/API/Crypto/getRandomValues +translation_of_original: Web/API/RandomSource +--- +<p>{{APIRef("Web Crypto API")}}</p> + +<p><strong><code>RandomSource</code></strong> 代表密码学安全随机数的来源。它可以通过全局对象的 {{domxref("Crypto")}} 获取:网页中的 {{domxref("Window.crypto")}},Workrt 里面的 {{domxref("WorkerGlobalScope.crypto")}}。</p> + +<p><code>RandomSource</code> 不是一个接口,这个类型的对象不可以被创建。</p> + +<h2 id="属性">属性</h2> + +<p><em><code>RandomSource</code> 既没有定义也没有属性。</em></p> + +<dl> +</dl> + +<h2 id="方法">方法</h2> + +<dl> + <dt>{{ domxref("RandomSource.getRandomValues()") }}</dt> + <dd>使用密码学可靠的随机值填充传递过来的 {{ domxref("ArrayBufferView") }}。</dd> +</dl> + +<h2 id="Specification" name="Specification">标准</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('Web Crypto API', '#dfn-RandomSource')}}</td> + <td>{{Spec2('Web Crypto API')}}</td> + <td>Initial definition</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Edge</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>11.0 {{ webkitbug("22049") }}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop(21)}} [1]</td> + <td>11.0</td> + <td>15.0</td> + <td>3.1</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Edge</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatNo() }}</td> + <td>23</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoMobile(21)}}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>6</td> + </tr> + </tbody> +</table> +</div> + +<p>[1] Although the transparent <code>RandomSource</code> is only available since Firefox 26, the feature was available in Firefox 21.</p> + +<h2 id="参见">参见</h2> + +<ul> + <li>通过 {{ domxref("Window.crypto") }} 获取一个 {{domxref("Crypto")}} 对象。</li> + <li>{{jsxref("Math.random")}},一个非密码学安全来源的随机数。</li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/document/characterset/index.html b/files/zh-cn/conflicting/web/api/document/characterset/index.html new file mode 100644 index 0000000000..00701e8acf --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document/characterset/index.html @@ -0,0 +1,21 @@ +--- +title: document.inputEncoding +slug: Web/API/Document/inputEncoding +translation_of: Web/API/Document/characterSet +translation_of_original: Web/API/Document/inputEncoding +--- +<p>{{ ApiRef() }} {{ deprecated_header() }}</p> +<h3 id="概述">概述</h3> +<p>返回一个字符串,代表当前文档渲染时所使用的编码.(比如<code>utf-8</code>).</p> +<div class="warning"> + <strong>警告:</strong> 不要再使用该属性.该属性在DOM 4 规范(草案)中已经被废弃. Gecko 在未来的版本中将会删除它.</div> +<h3 id="语法">语法</h3> +<pre class="eval"><var>encoding</var> = <code>document.inputEncoding;</code> +</pre> +<p><code>inputEncoding</code> 是个只读属性.</p> +<h3 id="规范">规范</h3> +<ul> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-3-Core/core.html#Document3-inputEncoding">DOM Level 3 Core</a></li> + <li>This has been removed from {{ spec("http://www.w3.org/TR/domcore/","DOM Core Level 4","WD") }}</li> +</ul> +<p>{{ languages( {"en": "en/DOM/document.inputEncoding" } ) }}</p> diff --git a/files/zh-cn/conflicting/web/api/document/createevent/index.html b/files/zh-cn/conflicting/web/api/document/createevent/index.html new file mode 100644 index 0000000000..8b9c249c71 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document/createevent/index.html @@ -0,0 +1,35 @@ +--- +title: Event.createEvent() +slug: Web/API/Event/createEvent +tags: + - DOM + - Event + - JavaScript + - Method +translation_of: Web/API/Document/createEvent +translation_of_original: Web/API/Event/createEvent +--- +<p>{{APIRef("DOM")}}</p> + +<p>创建一个新的事件(Event),随之必须调用自身的 init 方法进行初始化。</p> + +<h3 id="语法">语法</h3> + +<pre><code>document.createEvent(type) </code></pre> + +<dl> + <dt><code>type</code></dt> + <dd>指明待创建事件对象的类型的字符串</dd> +</dl> + +<p>此方法返回一个新的特定类型的 DOM {{ domxref("Event") }} 对象,此对象在使用前必须经过初始化(init)。</p> + +<h3 id="示例">示例</h3> + +<pre>var newEvent = document.createEvent("UIEvents");</pre> + +<h3 id="规范">规范</h3> + +<ul> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-document" title="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-document">DOM Level 2 Events</a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/document/hasfocus/index.html b/files/zh-cn/conflicting/web/api/document/hasfocus/index.html new file mode 100644 index 0000000000..df29adde76 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document/hasfocus/index.html @@ -0,0 +1,79 @@ +--- +title: HTML 焦点管理 +slug: Web/HTML/Focus_management_in_HTML +tags: + - DOM + - HTML + - HTML5 + - 焦点 +translation_of: Web/API/Document/hasFocus +translation_of_original: Web/HTML/Focus_management_in_HTML +--- +<p>重定向 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus">Document.hasFocus()</a></p> + +<p> </p> + +<p>在 HTML5 工作草案中,DOM 属性 <code><a href="/cn/DOM/document.activeElement" title="en/DOM/document.activeElement">activeElement</a></code> 与方法 <code><a href="/cn/DOM/document.hasFocus" title="en/DOM/document.hasFocus">hasFocus()</a></code> 为程序员提供了更好的控制页面交互的能力,特别是对于用户行为引发的交互。例如,它们都可以用于统计使用目的,跟踪页面特定链接的点击次数,计算元素获得焦点的次数等等。此外,当与 AJAX 技术结合以后,将会减少向服务器请求的数目,这取决于用户的活跃程度和页面的布局。</p> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{CompatibilityTable()}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("1.9.2")}}<sup>[1]</sup></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoMobile("2.0")}}<sup>[1]</sup></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<h3 id="浏览器相关注释">浏览器相关注释</h3> + +<h4 id="Gecko_notes">Gecko notes</h4> + +<p>[1] Gecko 8.0 {{geckoRelease("8.0")}} 开始,Firefox 会在任意 <code>tabindex</code> 值大于 0 的元素周围绘制一个焦点框,而不只是一小部分元素。一部分元素例外: {{HTMLElement("input")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}}, {{HTMLElement("textarea")}}, {{HTMLElement("iframe")}}, {{HTMLElement("frame")}}, {{HTMLElement("body")}} 和 {{HTMLElement("html")}}。</p> + +<h2 id="另请参阅">另请参阅</h2> + +<ul> + <li>{{domxref("document.activeElement")}}</li> + <li>{{domxref("document.hasFocus")}}</li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/document_object_model/index.html b/files/zh-cn/conflicting/web/api/document_object_model/index.html new file mode 100644 index 0000000000..80f115abfd --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document_object_model/index.html @@ -0,0 +1,52 @@ +--- +title: 前言 +slug: Web/API/Document_Object_Model/Preface +translation_of: Web/API/Document_Object_Model +translation_of_original: Web/API/Document_Object_Model/Preface +--- +<p>{{ ApiRef() }}</p> +<h3 id="About_This_Reference" name="About_This_Reference">关于此参考文档</h3> +<p>本节将描述与此向导本身相关的一些内容,内容包括它是做什么的,里面的信息是如何呈现的,以及怎样在你DOM开发中如何使用这份参考文档中的示例。</p> +<p>注意,这份文档尚在开发中,并没有完整包含Gecko中所有已经移植的DOM方法及其属性,但是,文档中的每一个小节(例如,DOM文件参考)中所描述的对象是完整的。今后当某个API库的成员的信息可用时,它将会被整合到此文档中。</p> +<h3 id="哪些人应该阅读这份指南">哪些人应该阅读这份指南</h3> +<p>这份Gecko DOM参考文档的读者应该是一位web开发人员或者是一位对网页制作有一定了解的熟练web用户。这份文档对读者对DOM、XML、web服务或者web标准,甚至JavaScript——DOM呈现给读者的语言——的熟练度都没有要求。但是,本文档假定读者至少对HTML、标签、网页的基本结构、浏览器以及样式表是熟悉的。</p> +<p>在这里,介绍性的资料在展示的同时伴随有许多示例,并且高等级的解释对没有经验的和经验丰富的web开发者都同样有用,并且也并不仅仅针对入门开发者。然而,这是一份正在不断改进中的API参考手册。</p> +<h3 id="什么是Gecko?">什么是Gecko?</h3> +<p>Mozilla,Firefox, Netscape 6以上版本,以及一些基于Mozilla的其他浏览器都有一个相同的对DOM的实现。这是因为它们使用的是相同的技术。</p> +<p>Gecko,即在上述各种浏览器中处理HTML的解析,页面的排版,文档对象模型,以及整个应用界面的渲染的软件组件,是一个快速的、兼容多种标准的渲染引擎。它移植了W3C的DOM标准以及出现在网页页面和应用界面(或者称为chrome)中的类DOM(但尚未标准化)的浏览器对象模型(即所谓window等的)。</p> +<p>尽管应用界面和页面内容在不同的浏览器里的呈现方式不一样,但是DOM期望它们统一地作为一种节点的分层结构。</p> +<h3 id="API语法">API语法</h3> +<p>API参考里的每个描述都包括语法、输入输出参数(包括返回类型),一个例子,额外的一些提示,以及指向对应参考文档的链接。</p> +<p>只读的属性只能被读取。因为它们无法被设置,所以通常以一个单独的一行语法表示。例如screen对象的只读属性availHeight使用的语法如下:</p> +<pre>iAvail = window.screen.availHeight +</pre> +<p>这意味着你只能把该只读属性放在等式的右边。</p> +<p>可读/写的属性,既能被读取也能被写入:</p> +<pre>msg = window.status +window.status = msg +</pre> +<p>一般来说,描述对象的成员时,对象的格式声明通常都带有一个简单的类型描述符,例如,对所有的元素使用element,对所有的顶层文档对象使用document,对所有的表对象使用table等(详见<a href="/zh-CN/Gecko_DOM_Reference/Introduction#Important_Data_Types" title="zh-CN/Gecko_DOM_Reference/Introduction#Important_Data_Types">重要的数据类型</a>)。</p> +<h3 id="Using_the_Examples" name="Using_the_Examples">如何使用示例</h3> +<p>本参考文档中的许多示例都是完整的文档,你可以把他们复制粘贴到一个新的文件,然后在浏览器中打开它。</p> +<p>其他的例子是一些代码片段。你可以把它们加入到JavaScript的回调函数中来执行。</p> +<p>例如,这个关于<a href="/zh-CN/DOM/window.document" title="zh-CN/DOM/window.document">window.document</a>属性的例子能通过一个函数来测试。这里,它通过一个按钮的<code>onclick </code>属性来调用。</p> +<pre class="brush: html"><html> +<head> +<title>Test Page</title> +<script type="text/javascript"> +function testWinDoc() { + + var doc= window.document; + + alert(doc.title); + +} +</script> +</head> + +<body> + <button onclick="testWinDoc();">test document property</button> +</body> +</html> +</pre> +<p>其他一些尚未完整打包的对象成员也采用与此类似的函数和页面。参见<a href="/zh-CN/Gecko_DOM_Reference/Introduction#Testing_the_DOM_API" title="zh-CN/Gecko_DOM_Reference/Introduction#Testing_the_DOM_API">测试DOM API</a>,可以一次对各种API的做一次“无害测试”。</p> diff --git a/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html b/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html new file mode 100644 index 0000000000..e09b7ab597 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html @@ -0,0 +1,33 @@ +--- +title: DOM 开发者指南 +slug: Web/Guide/API/DOM +tags: + - API + - DOM + - Guide + - NeedsTranslation + - TopicStub +translation_of: Web/API/Document_Object_Model +translation_of_original: Web/Guide/API/DOM +--- +<p>{{draft}}</p> + +<p><a href="https://developer.mozilla.org/docs/DOM">文档对象模型</a>( <a href="/docs/DOM">Document Object Model</a>) 是为 <a href="/en-US/docs/HTML">HTML</a> 和<a href="/en-US/docs/XML">XML</a> 文档编写的应用程序接口。它为文档提供了结构化的描述, 使得开发者能够修改它们的内容和展现方式. 更重要的是, 它可以将网页与脚本或编程语言连接起来。</p> + +<p>开发者能用来修改和创建网页的所有性质、方法和事件都被组织到<a href="/en-US/docs/Gecko_DOM_Reference">对象</a>( <a href="/en-US/docs/Gecko_DOM_Reference">objects</a>)中, (例如, document 对象代表着文档本身,table 对象代表 一个 HTML 表格元素等等)。在较新的网络浏览器中,这些对象都可以用脚本语言获取。</p> + +<p>DOM模型常被用来与 <a href="/en-US/docs/JavaScript">JavaScript</a>交互。然而,DOM是独立于任何编程语言之外而设计的,这使得文档的结构化描述可以从一个<a href="https://developer.mozilla.org/en-US/docs/DOM/DOM_Reference">单个、兼容的接口</a>获取,尽管我们青睐于Javascript,但我们可以为任何语言创建DOM的引用接口。</p> + +<p><a href="http://www.w3.org/">万维网联盟组织</a>( <a href="http://www.w3.org/">World Wide Web Consortium</a> )为DOM建立了一套标准, 叫做<a href="http://www.w3.org/DOM/"> W3C DOM</a>。它被如今大多数主流浏览器所支持,使得可以开发出强大的跨浏览器应用。</p> + +<h2 id="Why_is_the_DOM_support_in_Mozilla_important.3F" name="Why_is_the_DOM_support_in_Mozilla_important.3F">为什么DOM很重要?</h2> + +<p>"动态超文本链接语言" (<a href="/en-US/docs/DHTML">DHTML</a>) 是一个被一些开发者们用来描述结合HTML、样式表、脚本而使文档富有动态效果技术的名词。 W3C DOM工作组致力于开发可操作的、不受语言限制并被大家所认同的解决方案 (可参见 <a href="http://www.w3.org/DOM/faq.html">W3C 问答</a>).</p> + +<p>正如 Mozilla 的标题"网络应用程序平台”所强调的, 对DOM的支持是核心的特点,也是Mozilla能取代其它浏览器所必需的特点。更为重要的事实是--Mozilla(包括Firefox和Thunderbird)的用户界面都是用<a href="https://developer.mozilla.org/en-US/docs/XUL">XUL</a>创建的,并且用DOM<a href="https://developer.mozilla.org/en-US/docs/Dynamically_modifying_XUL-based_user_interface">修改自己的用户界面</a>。</p> + +<h2 id="更多关于DOM的内容">更多关于DOM的内容</h2> + +<p>{{LandingPageListSubpages}}</p> + +<p> </p> diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html new file mode 100644 index 0000000000..6fb591e1da --- /dev/null +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html @@ -0,0 +1,45 @@ +--- +title: Document.elementFromPoint() +slug: Web/API/Document/elementFromPoint +translation_of: Web/API/DocumentOrShadowRoot/elementFromPoint +translation_of_original: Web/API/Document/elementFromPoint +--- +<div> + {{APIRef()}} {{Fx_minversion_header(3)}}</div> +<h2 id="Summary" name="Summary">概述</h2> +<p>返回当前文档上处于指定坐标位置最顶层的元素, 坐标是相对于包含该文档的浏览器窗口的左上角为原点来计算的, 通常 x 和 y 坐标都应为正数.</p> +<h2 id="Syntax" name="Syntax">语法</h2> +<pre><em>var element</em> = document.elementFromPoint(<em>x</em>, <em>y</em>);</pre> +<ul> + <li><code>element</code> 是返回的DOM<a href="/en-US/docs/DOM/element" title="DOM/element">元素</a>.</li> + <li><code>x</code> 和 <code>y</code> 是坐标数值, 不需要单位比如px.</li> +</ul> +<h2 id="Example" name="Example">示例</h2> +<pre class="brush:html"><!DOCTYPE html> +<html lang="en"> +<head> +<title>elementFromPoint example</title> + +<script> +function changeColor(newColor) { + elem = document.elementFromPoint(2, 2); + elem.style.color = newColor; +} +</script> +</head> + +<body> +<p id="para1">Some text here</p> +<button onclick="changeColor('blue');">blue</button> +<button onclick="changeColor('red');">red</button> +</body> +</html> +</pre> +<h2 id="Notes" name="Notes">附注</h2> +<p>If the element at the specified point belongs to another document (for example, an iframe's subdocument), the element in the DOM of the document the method is called on (in the iframe case, the iframe itself) is returned. If the element at the given point is anonymous or XBL generated content, such as a textbox's scroll bars, then the first non-anonymous ancestor element (for example, the textbox) is returned.</p> +<p>If the specified point is outside the visible bounds of the document or either coordinate is negative, the result is <code>null</code>.</p> +<p>{{Note("Callers from XUL documents should wait until the <code>onload</code> event has fired before calling this method.")}}</p> +<h2 id="Specification" name="Specification">规范</h2> +<ul> + <li>Preliminary specification: <code><a class="external" href="http://dev.w3.org/csswg/cssom-view/#dom-document-elementfrompoint">elementFromPoint</a></code></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html new file mode 100644 index 0000000000..9a7ee01503 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html @@ -0,0 +1,129 @@ +--- +title: Document.elementsFromPoint() +slug: Web/API/Document/elementsFromPoint +translation_of: Web/API/DocumentOrShadowRoot/elementsFromPoint +translation_of_original: Web/API/Document/elementsFromPoint +--- +<div>{{APIRef("DOM")}}{{SeeCompatTable}}</div> + +<p><code><strong>elementsFromPoint()</strong></code> 方法可以获取到当前视口内指定坐标处,由里到外排列的所有元素。</p> + +<h2 id="语法">语法</h2> + +<pre class="brush: js">var<em> elements</em> = <em>document</em>.elementsFromPoint(<em>x</em>, <em>y</em>);</pre> + +<h3 id="返回值">返回值</h3> + +<p>一个包含多个元素的数组</p> + +<h3 id="参数">参数</h3> + +<dl> + <dt>x</dt> + <dd>当前视口内某一点的横坐标</dd> + <dt>y</dt> + <dd>当前视口内某一点的纵坐标</dd> +</dl> + +<h2 id="Example" name="Example">示例</h2> + +<h3 id="HTML">HTML</h3> + +<pre class="brush: html"><div> + <p>Some text</p> +</div> +<p>Elements at point 30, 20:</p> +<div id="output"></div> +</pre> + +<h3 id="JavaScript">JavaScript</h3> + +<pre class="brush: js;highlight[1]">var output = document.getElementById("output"); +if (document.elementsFromPoint) { + var elements = document.elementsFromPoint(30, 20); + for(var i = 0; i < elements.length; i++) { + output.textContent += elements[i].localName; + if (i < elements.length - 1) { + output.textContent += " < "; + } + } +} else { + output.innerHTML = "<span style=\"color: red;\">" + + "您的浏览器不支持 <code>document.elementsFromPoint()</code>" + + "</span>"; +}</pre> + +<p>{{EmbedLiveSample('Example', '420', '120')}}</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('CSSOM View', '#dom-document-elementsfrompoint', 'elementsFromPoint')}}</td> + <td>{{Spec2('CSSOM View')}}</td> + <td>Initial definition.</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td> {{CompatChrome(43.0)}}</td> + <td>{{CompatGeckoDesktop("46.0")}}<sup>[1]</sup></td> + <td>10.0 {{property_prefix("ms")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatSafari(11)}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + <th>Chrome for Android</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatChrome(43.0)}}</td> + <td>{{CompatGeckoMobile("46.0")}}<sup>[1]</sup></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatSafari(11)}}</td> + <td>{{CompatChrome(43.0)}}</td> + </tr> + </tbody> +</table> +</div> + +<p> </p> diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html new file mode 100644 index 0000000000..73b3a4ce6b --- /dev/null +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html @@ -0,0 +1,15 @@ +--- +title: document.getSelection +slug: Web/API/Document/getSelection +translation_of: Web/API/DocumentOrShadowRoot/getSelection +translation_of_original: Web/API/Document/getSelection +--- +<article class="approved text-content" style="padding-right: 10px; width: 652px; float: left;"> +<div class="boxed translate-rendered" style=""> +<p>{{APIRef("DOM")}}</p> + +<p>该方法的功能等价于 {{domxref("Window.getSelection()")}} 方法;其返回一个 {{domxref("Selection")}} 对象,表示文档中当前被选择的文本。</p> +</div> +</article> + +<p> </p> diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html new file mode 100644 index 0000000000..de44c8537b --- /dev/null +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html @@ -0,0 +1,26 @@ +--- +title: Document.styleSheets +slug: Web/API/Document/styleSheets +translation_of: Web/API/DocumentOrShadowRoot/styleSheets +translation_of_original: Web/API/Document/styleSheets +--- +<div>{{APIRef}}</div> + +<p><strong><code>Document.styleSheets</code></strong> 只读属性,返回一个由 {{domxref("StyleSheet ")}} 对象组成的 {{domxref("StyleSheetList")}},每个 {{domxref("StyleSheet ")}} 对象都是一个文档中链接或嵌入的样式表。</p> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="syntaxbox">let <var>styleSheetList</var> = <em>document</em>.styleSheets; +</pre> + +<p>返回的对象是一个 {{domxref("StyleSheetList")}}。</p> + +<p>它是一个 {{domxref("StyleSheet")}} 对象的有序集合。<code><em>styleSheetList</em>.item(<em>index</em>)</code> 或 <code><em>styleSheetList</em>{{ mediawiki.External('<em>index</em>') }}</code> 根据它的索引(索引基于0)返回一个单独的样式表对象。</p> + +<pre class="syntaxbox"> </pre> + +<h2 id="Specification" name="Specification">规范</h2> + +<ul> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-DocumentStyle-styleSheets">DOM Level 2 Style: styleSheets</a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/dommatrix/index.html b/files/zh-cn/conflicting/web/api/dommatrix/index.html new file mode 100644 index 0000000000..16fe55276d --- /dev/null +++ b/files/zh-cn/conflicting/web/api/dommatrix/index.html @@ -0,0 +1,94 @@ +--- +title: CSSMatrix +slug: Web/API/CSSMatrix +translation_of: Web/API/DOMMatrix +translation_of_original: Web/API/CSSMatrix +--- +<div>{{APIRef("CSSOM")}}{{Non-standard_header}}</div> + +<p><strong><code>CSSMatrix</code></strong> 代表可以用于2D或3D变换的4x4齐次矩阵。据说这个类曾经是 CSS Transitions Module Level 3 的一部分,但在现在的工作草案里不存在 。请使用 <a href="/en-US/docs/Web/API/DOMMatrix"><code>DOMMatrix</code></a> 。</p> + +<h2 id="Specifications" name="Specifications">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('Compat', '#webkitcssmatrix-interface', 'WebKitCSSMatrix')}}</td> + <td>{{Spec2('Compat')}}</td> + <td>Initial standardization of the WebKit-prefixed version, <code>WebKitCSSMatrix</code>.</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Edge</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>10<sup>[1]</sup></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatVersionUnknown}}<sup>[2]</sup></td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Edge</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>基本支持</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>11<sup>[1]</sup></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatVersionUnknown}}<sup>[2]</sup></td> + </tr> + </tbody> +</table> +</div> + +<p>[1] Internet Explorer 将此 API<code>实现为MSCSSMatrix</code>。在版本11中,加入了别名<code>WebKitCSSMatrix</code>。</p> + +<p>[2] WebKit 将此 API<code>实现为WebKitCSSMatrix</code>。</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="https://msdn.microsoft.com/en-us/library/ie/hh772390(v=vs.85).aspx"><code>MSCSSMatrix</code> documentation on MSDN</a></li> + <li><a href="https://developer.apple.com/library/safari/documentation/AudioVideo/Reference/WebKitCSSMatrixClassReference/index.html"><code>WebKitCSSMatrix</code> documentation at Safari Developer Library</a></li> + <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=717722">Mozilla bug 717722: implement <code>(WebKit)CSSMatrix()</code></a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/element/index.html b/files/zh-cn/conflicting/web/api/element/index.html new file mode 100644 index 0000000000..2a489d3b22 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/element/index.html @@ -0,0 +1,48 @@ +--- +title: Slotable +slug: Web/API/Slotable +tags: + - API + - Web Components + - 参考 + - 接口 +translation_of: Web/API/Slottable +translation_of_original: Web/API/Slotable +--- +<p>{{APIRef("Shadow DOM")}}</p> + +<p><code>Slotable</code> mixin 定义了允许节点成为 {{htmlelement("slot")}} 元素的内容的特性——下面的特性被包含在 {{domxref("Element")}} 和 {{domxref("Text")}} API 之中。</p> + +<h2 id="属性">属性</h2> + +<dl> + <dt>{{domxref("Slotable.assignedSlot")}} {{readonlyInline}}</dt> + <dd>返回节点所插入的 {{htmlelement("slot")}} 元素。</dd> +</dl> + +<h2 id="方法">方法</h2> + +<p>无。</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">备注</th> + </tr> + <tr> + <td>{{SpecName('DOM WHATWG','#slotable','Slotable')}}</td> + <td>{{Spec2('DOM WHATWG')}}</td> + <td>Initial definition.</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("api.Slotable")}}</p> diff --git a/files/zh-cn/conflicting/web/api/event/composedpath/index.html b/files/zh-cn/conflicting/web/api/event/composedpath/index.html new file mode 100644 index 0000000000..61bfdf1366 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/event/composedpath/index.html @@ -0,0 +1,90 @@ +--- +title: Event.deepPath +slug: Web/API/Event/deepPath +translation_of: Web/API/Event/composedPath +translation_of_original: Web/API/Event/deepPath +--- +<p>{{SeeCompatTable}}{{APIRef("Shadow DOM")}}</p> + +<p><span class="seoSummary">{{domxref("Event")}}的<strong><code>deepPath</code></strong> 属性返回事件冒泡过程所有经过的节点所构成的{{jsxref("Array")}}数组</span></p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">var <em>nodes</em>[] = Event.deepPath</pre> + +<h3 id="返回值">返回值</h3> + +<p>一组节点 构成的{{jsxref("Array")}}数组</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规格</th> + <th scope="col">状态</th> + <th scope="col">评语</th> + </tr> + <tr> + <td>{{SpecName('Shadow DOM','#widl-Event-deepPath-sequence-EventTarget','deepPath')}}</td> + <td>{{Spec2('Shadow DOM')}}</td> + <td>Initial definition.</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatChrome(53.0)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Firefox Mobile (Gecko)</th> + <th>Firefox OS</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + <th>Chrome for Android</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatChrome(53.0)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatChrome(53.0)}}</td> + </tr> + </tbody> +</table> +</div> diff --git a/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html b/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html new file mode 100644 index 0000000000..f637813381 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html @@ -0,0 +1,9 @@ +--- +title: 为这个EventTarget附加事件. +slug: Web/API/EventTarget/attachEvent +tags: + - Junk +translation_of: Web/API/EventTarget/addEventListener +translation_of_original: Web/API/EventTarget/attachEvent +--- +<p>{{DOMxRef("EventTarget.addEventListener","EventTarget.addEventListener()")}}</p> diff --git a/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html b/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html new file mode 100644 index 0000000000..edc74b2306 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html @@ -0,0 +1,93 @@ +--- +title: EventTarget.fireEvent() +slug: Web/API/EventTarget/fireEvent +translation_of: Web/API/EventTarget/dispatchEvent +translation_of_original: Web/API/EventTarget/fireEvent +--- +<p>{{APIRef("DOM Events")}}</p> + +<p>{{ Non-standard_header() }}</p> + +<h2 id="概述">概述</h2> + +<p>这是微软IE浏览器用以替代{{domxref("EventTarget.dispatchEvent()")}}的私有方法,与{{domxref("EventTarget.dispatchEvent()")}}不同的是通过<code>fireEvent()</code> 触发的事件不会触发事件的默认行为,例如,通过fireEvent()触发<input type="checkbox">的点击事件并不会切换checkbox的选中状态</p> + +<p>语法</p> + +<pre class="syntaxbox"><em>cancelled</em> = <em>target</em>.fireEvent(<em>eventNameWithOn</em>, <em>event</em>) +</pre> + +<dl> + <dt>target</dt> + <dd>要触发事件的元素</dd> + <dt>eventNameWithOn</dt> + <dd>要触发事件的名字,前缀为“on”,例如,可以用过"onclick"来触发点击事件</dd> + <dt>event</dt> + <dd>要触发的事件对象</dd> + <dt>cancelled</dt> + <dd>布尔值,事件是否被事件句柄取消</dd> +</dl> + +<h2 id="规范">规范</h2> + +<p>无此部分的规范</p> + +<p>微软的描述: <a href="https://msdn.microsoft.com/en-us/library/ms536423(v=vs.85).aspx">has a description on MSDN</a>.</p> + +<h2 id="Browser_Compatibility" name="Browser_Compatibility">浏览器兼容性</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>6 到 10 [1]</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatNo() }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatNo() }}</td> + </tr> + </tbody> +</table> +</div> + +<p>[1]: fireEvent()在IE11+已经不再支持,{{domxref("EventTarget.dispatchEvent()")}}在IE9+已经支持</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="http://help.dottoro.com/ljvtddtm.php">Dottoro Web Reference article</a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html b/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html new file mode 100644 index 0000000000..3b4cbcfd90 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html @@ -0,0 +1,97 @@ +--- +title: EventTarget.detachEvent() +slug: Web/API/EventTarget/detachEvent +tags: + - API + - DOM + - Method + - Non-standard +translation_of: Web/API/EventTarget/removeEventListener +translation_of_original: Web/API/EventTarget/detachEvent +--- +<p>{{APIRef("DOM Events")}}</p> + +<p>{{ Non-standard_header() }}</p> + +<h2 id="简介">简介</h2> + +<p>这是Microsoft Internet Explorer专有的用于替代标准的 {{domxref("EventTarget.removeEventListener()")}} 的方法。</p> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="syntaxbox"><em>target</em>.detachEvent(<em>eventNameWithOn</em>, <em>callback</em>) +</pre> + +<dl> + <dt>target</dt> + <dd>将要移除事件的DOM节点</dd> + <dt>eventNameWithOn</dt> + <dd>将要移除的事件名,以“on”为前缀(例如它是一个事件处理程序)。 例如,您可以使用“onclick”移除点击事件的事件处理程序。</dd> + <dt>callback</dt> + <dd>注销事件后的回调函数</dd> +</dl> + +<h2 id="详细">详细</h2> + +<p>任何规范没有此部分。</p> + +<p>微软在 <a href="https://msdn.microsoft.com/en-us/library/ms536411(v=vs.85).aspx">MSDN</a> 上有相关描述。</p> + +<h2 id="Browser_Compatibility" name="Browser_Compatibility">浏览器兼容性</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>特征</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>6 至 10 [1]</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatNo() }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>特征</th> + <th>Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatUnknown() }}</td> + <td>{{ CompatNo() }}</td> + </tr> + </tbody> +</table> +</div> + +<p>[1]: <code>detachEvent()</code> 在 IE11+ 中不再支持。 {{domxref("EventTarget.removeEventListener()")}} 在 IE9+ 中支持。</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{ domxref("EventTarget.attachEvent()") }}</li> + <li>{{ domxref("EventTarget.fireEvent()") }}</li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html b/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html new file mode 100644 index 0000000000..90ace79b50 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html @@ -0,0 +1,81 @@ +--- +title: File System API guide +slug: WebGuide/API/File_System +translation_of: Web/API/File_and_Directory_Entries_API/Introduction +translation_of_original: WebGuide/API/File_System +--- +<p>{{ SeeCompatTable() }}</p> +<p>The File System API simulates a local file system that web apps can navigate around. You can develop apps that can read, write, and create files and directories in a virtual, sandboxed file system.</p> +<p>The asynchronous API methods return without blocking the calling thread. The asynchronous API doesn't give you data by returning values; instead, you have to pass a callback function. The synchronous API is intended to be used inside <a href="/en/DOM/Worker" title="Worker">WebWorkers</a>.</p> +<p>For an overview of the File System API, see the following articles:</p> +<p>{{ListSubpages}}</p> +<h2 id="Browser_Compatibility" name="Browser_Compatibility">Browser compatibility</h2> +<p>{{ CompatibilityTable() }}</p> +<div id="compat-desktop"> + <table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Asynchronous API</td> + <td>13 {{ property_prefix("webkit") }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>15 {{ property_prefix("webkit") }}</td> + <td>{{ CompatNo() }}</td> + </tr> + <tr> + <td>Synchronous API</td> + <td>13 {{ property_prefix("webkit") }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>15 {{ property_prefix("webkit") }}</td> + <td>{{ CompatNo() }}</td> + </tr> + </tbody> + </table> +</div> +<div id="compat-mobile"> + <table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Asynchronous API</td> + <td>{{ CompatNo() }}</td> + <td>0.16{{ property_prefix("webkit") }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>14 {{ property_prefix("webkit") }}</td> + <td>{{ CompatNo() }}</td> + </tr> + <tr> + <td>Synchronous API</td> + <td>{{ CompatNo() }}</td> + <td>0.16{{ property_prefix("webkit") }}</td> + <td>{{ CompatNo() }}</td> + <td>{{ CompatNo() }}</td> + <td>14 {{ property_prefix("webkit") }}</td> + <td>{{ CompatNo() }}</td> + </tr> + </tbody> + </table> +</div> +<h2 id="See_also">See also</h2> +<ul> + <li><a href="/en-US/docs/Web/Reference/File_System_API" title="/en-US/docs/Web/Reference/File_System_API">File System API reference</a></li> + <li>Specification: {{ spec("http://dev.w3.org/2009/dap/file-system/pub/FileSystem/", "File API: Directories and System Specification", "WD") }}</li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/geolocation/index.html b/files/zh-cn/conflicting/web/api/geolocation/index.html new file mode 100644 index 0000000000..f5432039ba --- /dev/null +++ b/files/zh-cn/conflicting/web/api/geolocation/index.html @@ -0,0 +1,105 @@ +--- +title: NavigatorGeolocation +slug: Web/API/NavigatorGeolocation +translation_of: Web/API/Geolocation +translation_of_original: Web/API/NavigatorGeolocation +--- +<p>{{APIRef("Geolocation API")}}</p> + +<p><code><strong>NavigatorGeolocation</strong></code> contains a creation method allowing objects implementing it to obtain a {{domxref("Geolocation")}} instance.</p> + +<p>There is no object of type <code>NavigatorGeolocation</code>, but some interfaces, like {{domxref("Navigator")}} implements it.</p> + +<h2 id="Properties">Properties</h2> + +<p><em>The <code>NavigatorGeolocation</code></em><em> interface doesn't inherit any property.</em></p> + +<dl> + <dt>{{domxref("NavigatorGeolocation.geolocation")}} {{readonlyInline}}</dt> + <dd>Returns a {{domxref("Geolocation")}} object allowing accessing the location of the device.</dd> +</dl> + +<h2 id="Methods">Methods</h2> + +<p><em>The </em><em><code>NavigatorGeolocation</code></em><em> interface neither implements, nor inherit any method.</em></p> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('Geolocation', '#navi-geo', 'NavigatorGeolocation')}}</td> + <td>{{Spec2('Geolocation')}}</td> + <td>Initial specification.</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>5</td> + <td>{{CompatGeckoDesktop("1.9.1")}}</td> + <td>9</td> + <td>10.60<br> + Removed in 15.0<br> + Reintroduced in 16.0</td> + <td>5</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatUnknown()}}</td> + <td>{{CompatUnknown()}}</td> + <td>{{CompatGeckoMobile("4")}}</td> + <td>{{CompatUnknown()}}</td> + <td>10.60</td> + <td>{{CompatUnknown()}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/WebAPI/Using_geolocation" title="/en-US/docs/WebAPI/Using_geolocation">Using geolocation. </a></li> +</ul> + +<p> </p> diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html new file mode 100644 index 0000000000..2ff983926f --- /dev/null +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html @@ -0,0 +1,143 @@ +--- +title: Element.ongotpointercapture +slug: Web/API/Element/ongotpointercapture +tags: + - API + - DOM + - Element + - Event Handler + - Pointer Events + - Property + - Reference + - 事件句柄 + - 元素 + - 属性 + - 引用 + - 指针事件 +translation_of: Web/API/GlobalEventHandlers/ongotpointercapture +translation_of_original: Web/API/Element/ongotpointercapture +--- +<p>{{ ApiRef("DOM") }}</p> + +<p><code>ongotpointercapture</code> 是一个{{domxref("Element")}} 接口的{{domxref("EventHandler")}} 属性,返回一个{{event("gotpointercapture")}} 事件类型的事件句柄 (function) .</p> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="eval">var gotCaptureHandler = target.ongotpointercapture; +</pre> + +<h3 id="Return_Value" name="Return_Value">Return value</h3> + +<dl> + <dt><code>gotCaptureHandler</code></dt> + <dd>元素 <code>target</code> 的gotpointercapture 事件句柄。 .</dd> +</dl> + +<h2 id="Example">Example</h2> + +<pre class="brush: js"><html> +<script> +function overHandler(ev) { + // Determine the target event's gotpointercapture handler + var gotCaptureHandler = ev.target.ongotpointercapture; +} +function init() { + var el=document.getElementById("target"); + el.onpointerover = overHandler; +} +</script> +<body onload="init();"> +<div id="target"> Touch me ... </div> +</body> +</html> +</pre> + +<h2 id="Specifications" name="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('Pointer Events 2','#widl-Element-ongotpointercapture', 'ongotpointercapture')}}</td> + <td>{{Spec2('Pointer Events 2')}}</td> + <td>无稳定版</td> + </tr> + <tr> + <td>{{SpecName('Pointer Events', '#widl-Element-ongotpointercapture', 'ongotpointercapture')}}</td> + <td>{{Spec2('Pointer Events')}}</td> + <td>Initial definition.</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">Browser compatibility</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Edge</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}} <sup>[1]</sup></td> + <td>{{CompatIE("10")}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Chrome for Android</th> + <th>Edge</th> + <th>Firefox Mobile (Gecko)</th> + <th>Firefox OS</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatIE("10")}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<p>[1] Implementation withdrawn. See {{Bug("1166347")}}.</p> + +<h2 id="See_also" name="See_also">See also</h2> + +<ul> + <li>{{ event("gotpointercapture") }}</li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html new file mode 100644 index 0000000000..03a4b116b8 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html @@ -0,0 +1,43 @@ +--- +title: window.onmouseup +slug: Web/API/Window/onmouseup +translation_of: Web/API/GlobalEventHandlers/onmouseup +translation_of_original: Web/API/Window/onmouseup +--- +<p>{{ ApiRef() }}</p> +<h3 id="Summary" name="Summary">概述</h3> +<p>当前窗口的mouseup事件的事件句柄.</p> +<h3 id="Syntax" name="Syntax">语法</h3> +<pre class="eval">window.onmouseup = <em>funcRef</em>; +</pre> +<h3 id="Parameters" name="Parameters">参数</h3> +<ul> + <li><code>funcRef</code> 是个函数引用</li> +</ul> +<h3 id="Example" name="Example">例子</h3> +<pre>window.onmouseup = doFunc; +</pre> +<pre><html> +<head> + +<title>onmouseup测试</title> + +<script type="text/javascript"> + +window.onmouseup = mouseup; + +function mouseup() +{ + alert("检测到mouseup事件!"); +} +</script> +</head> + +<body> +<p>在页面上按下鼠标中某个键,保持几秒后松开.mouseup事件会在你松开鼠标时触发</p> +</body> +</html> +</pre> +<h3 id="Specification" name="Specification">规范</h3> +<p>没有任何公开的标准</p> +<p>{{ languages( { "ja": "ja/DOM/window.onmouseup" ,"en": "en/DOM/window.onmouseup" } ) }}</p> diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html new file mode 100644 index 0000000000..af48e1575f --- /dev/null +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html @@ -0,0 +1,54 @@ +--- +title: window.onscroll +slug: Web/API/Window/onscroll +translation_of: Web/API/GlobalEventHandlers/onscroll +translation_of_original: Web/API/Window/onscroll +--- +<p>{{ ApiRef() }}</p> +<h3 id="Summary" name="Summary">概述</h3> +<p>为当前页面的页面滚动事件添加事件处理函数.</p> +<h3 id="Syntax" name="Syntax">语法</h3> +<pre class="eval">window.onscroll = <em>funcRef</em>; +</pre> +<ul> + <li><code>funcRef</code> 是个函数类型的对象引用或者匿名函数.</li> +</ul> +<h3 id="Example" name="Example">例子</h3> +<pre class="brush: js">window.onscroll = function (e) { + // 当页面的滚动条滚动时,会执行这里的代码 +} +</pre> +<pre class="brush: html"><html> +<head> + +<title>onscroll test</title> + +<script type="text/javascript"> + +window.onscroll = scroll; + +function scroll() +{ + alert("检测到页面滚动事件:"+window.pageXOffset+" "+window.pageYOffset); + // 注意: window.innerWidth 和 window.innerHeight 可以获得页面可见区域的宽和高. +} +</script> +</head> + +<body> +<p>Resize the window</p> +<p>to a very small size,</p> +<p>and use the scrollbars</p> +<p>to move around the page content</p> +<p>in the window.</p> +</body> +</html> +</pre> +<h3 id="Notes" name="Notes">备注</h3> +<p>{{ Bug("189308") }}, 在旧版本的Gecko中(Gecko 1.8/Firefox 1.5之前), scroll 事件只会在用户拖动滚动条时发生,使用方向键和鼠标滚轮滚动页面则不会触发该事件.</p> +<p>当 window.scrollX/scrollY 不为 0时,意味着用户或者网页脚本已经执行了窗口的滚动行为.</p> +<h3 id="Specification" name="Specification">规范</h3> +<ul> + <li><a class="external" href="http://www.w3.org/TR/html5/webappapis.html#event-handlers-on-elements-document-objects-and-window-objects" title="http://www.w3.org/TR/html5/webappapis.html#event-handlers-on-elements-document-objects-and-window-objects">HTML5: Event handlers on elements, Document objects, and Window objects</a></li> +</ul> +<p>{{ languages( { "en": "en/DOM/window.onscroll"} ) }}</p> diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html new file mode 100644 index 0000000000..3bbf3d5ce4 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html @@ -0,0 +1,125 @@ +--- +title: GlobalEventHandlers.ontouchmove +slug: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove +translation_of: Web/API/GlobalEventHandlers/ontouchmove +translation_of_original: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove +--- +<div>{{ApiRef("HTML DOM")}}</div> + +<p>A {{domxref("GlobalEventHandlers","global event handler")}} for the {{event("touchmove")}} event.</p> + +<div class="note"> +<p><strong>注意:这个属性还没有正式的标准。它在 </strong>{{SpecName('Touch Events 2')}} {{Spec2('Touch Events 2')}} 说明书里被规定且不在 {{SpecName('Touch Events')}} {{Spec2('Touch Events')}}中。这个属性没有被广泛应用。</p> +</div> + +<h2 id="Syntax" name="Syntax">Syntax</h2> + +<pre class="eval">var moveHandler = someElement.ontouchmove; +</pre> + +<h3 id="Return_Value" name="Return_Value">Return value</h3> + +<dl> + <dt><code>moveHandler</code></dt> + <dd>The <em>touchmove</em> event handler for element <code>someElement</code>.</dd> +</dl> + +<h2 id="Example">Example</h2> + +<p>This example shows two ways to use <em>ontouchmove</em> to set an element's <em>touchmove</em> event handler.</p> + +<pre class="brush: js"><html> +<script> +function moveTouch(ev) { + // Process the event +} +function init() { + var el=document.getElementById("target1"); + el.ontouchmove = moveTouch; +} +</script> +<body onload="init();"> +<div id="target1"> Touch me ... </div> +<div id="target2" ontouchmove="moveTouch(event)"> Touch me ... </div> +</body> +</html> +</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('Touch Events 2','#widl-GlobalEventHandlers-ontouchmove')}}</td> + <td>{{Spec2('Touch Events 2')}}</td> + <td>Non-stable version.</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>Firefox OS</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{ event("touchmove") }}</li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html b/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html new file mode 100644 index 0000000000..01de770af7 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html @@ -0,0 +1,9 @@ +--- +title: Node.outerText +slug: Web/API/Node/outerText +tags: + - Node.outerText +translation_of: Web/API/HTMLElement/outerText +translation_of_original: Web/API/Node/outerText +--- +<p>请参阅 {{domxref("HTMLElement.outerText")}}</p> diff --git a/files/zh-cn/conflicting/web/api/htmlinputelement/index.html b/files/zh-cn/conflicting/web/api/htmlinputelement/index.html new file mode 100644 index 0000000000..0cccf89889 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/htmlinputelement/index.html @@ -0,0 +1,49 @@ +--- +title: HTMLInputElement.mozSetFileNameArray +slug: Web/API/HTMLInputElement/mozSetFileNameArray +translation_of: Web/API/HTMLInputElement +translation_of_original: Web/API/HTMLInputElement/mozSetFileNameArray +--- +<div> +<div> +<div> +<div>{{APIRef("HTML DOM")}}</div> +</div> +</div> +{{gecko_minversion_header("1.9.2")}}</div> + +<h3 id="Summary" name="Summary">概述</h3> + +<p>设置一个HTML <code>input</code>元素中选中的若干文件的路径以及文件名.</p> + +<div class="note"><strong>注:</strong> 该方法是Gecko私有的方法,在其他浏览器中不可用,且是个特权方法,不能在普通网页中使用.</div> + +<h3 id="Syntax" name="Syntax">语法</h3> + +<pre class="eval">inputElement.mozSetFileNameArray(<em>aFileNames, </em><em>aLength</em>); +</pre> + +<h3 id="Parameters" name="Parameters">参数</h3> + +<ul> + <li><code>aFileNames</code> 指定给该元素的若干个文件的文件名路径以及文件名.</li> + <li><code>aLength </code>需要指定文件的个数(<code>通常是</code>数组<code>aFileNames</code>的长度).</li> +</ul> + +<h3 id="Example" name="Example">示例</h3> + +<pre class="brush: js">var fileArray = {"/foo/bar.txt", "/foo/foosball.txt"}; + +inputElement.mozSetFileNameArray(fileArray, fileArray.length); +</pre> + +<h3 id="Specification" name="Specification">规范</h3> + +<p>非标准,Mozilla私有方法.</p> + +<h3 id="相关链接">相关链接</h3> + +<ul> + <li><a href="/zh-CN/DOM/Input" title="zh-CN/DOM/Input"><code>Input</code></a></li> + <li><a href="/zh-CN/DOM/Input.mozGetFileNameArray" title="zh-CN/DOM/Input.mozGetFileNameArray"><code>Input.mozGetFileNameArray</code></a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html b/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html new file mode 100644 index 0000000000..9a233b4d80 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html @@ -0,0 +1,74 @@ +--- +title: abort +slug: Web/Events/abort +tags: + - abort +translation_of: Web/API/HTMLMediaElement/abort_event +translation_of_original: Web/Events/abort +--- +<p>当一个资源的加载已中止时,将触发 <strong>abort</strong>事件。</p> + +<div class="note"> +<p>译者注:这个事件只在 IE 支持,试了最新的 Chrome、FireFox、Safari 都不支持。</p> +</div> + +<h2 id="常规信息">常规信息</h2> + +<dl> + <dt style="float: left; text-align: right; width: 120px;">规范</dt> + <dd style="margin: 0 0 0 120px;"><a class="external" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-abort">DOM L3</a></dd> + <dt style="float: left; text-align: right; width: 120px;">接口</dt> + <dd style="margin: 0 0 0 120px;">从UI组件产生为UIEvent , 否则为Event .</dd> + <dt style="float: left; text-align: right; width: 120px;">是否冒泡</dt> + <dd style="margin: 0 0 0 120px;">否</dd> + <dt style="float: left; text-align: right; width: 120px;">可取消默认行为</dt> + <dd style="margin: 0 0 0 120px;">否</dd> + <dt style="float: left; text-align: right; width: 120px;">目标对象</dt> + <dd style="margin: 0 0 0 120px;">元素(Element)</dd> + <dt style="float: left; text-align: right; width: 120px;">默认行为</dt> + <dd style="margin: 0 0 0 120px;">无</dd> +</dl> + +<h2 id="属性">属性</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">属性</th> + <th scope="col">类型</th> + <th scope="col">描述</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>target</code> {{readonlyInline}}</td> + <td>{{domxref("EventTarget")}}</td> + <td>产生该事件的对象(DOM树中最顶级的那个对象).</td> + </tr> + <tr> + <td><code>type</code> {{readonlyInline}}</td> + <td>{{domxref("DOMString")}}</td> + <td>事件类型.</td> + </tr> + <tr> + <td><code>bubbles</code> {{readonlyInline}}</td> + <td>{{jsxref("Boolean")}}</td> + <td>该事件是否冒泡.</td> + </tr> + <tr> + <td><code>cancelable</code> {{readonlyInline}}</td> + <td>{{jsxref("Boolean")}}</td> + <td>该事件是否可取消默认行为.</td> + </tr> + <tr> + <td><code>view</code> {{readonlyInline}}</td> + <td><a class="new" href="/zh-CN/docs/Web/API/WindowProxy" rel="nofollow" title="The documentation about this has not yet been written; please consider contributing!"><code>WindowProxy</code></a></td> + <td><a href="/zh-CN/docs/Web/API/Document/defaultView" title="In browsers, document.defaultView returns the window object associated with a document, or null if none is available."><code>document.defaultView</code></a> (该文档的<code>window</code>对象 )</td> + </tr> + <tr> + <td><code>detail</code> {{readonlyInline}}</td> + <td><code>long</code> (<code>float</code>)</td> + <td>0.</td> + </tr> + </tbody> +</table> diff --git a/files/zh-cn/conflicting/web/api/index.html b/files/zh-cn/conflicting/web/api/index.html new file mode 100644 index 0000000000..f1a247fd70 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/index.html @@ -0,0 +1,71 @@ +--- +title: Element.name +slug: Web/API/Element/name +translation_of: Web/API +translation_of_original: Web/API/Element/name +--- +<p>{{ APIRef() }}</p> + +<h2 id="Summary" name="Summary">概述</h2> + +<p><strong>name</strong> 获取或设置一个 DOM 对象的 <code>name</code> 属性;它只能应用于下列元素:{{ HTMLelement("a") }}, {{ HTMLelement("applet") }}, {{ HTMLelement("button") }}, {{ HTMLelement("form") }}, {{ HTMLelement("frame") }}, {{ HTMLelement("iframe") }}, {{ HTMLelement("img") }}, {{ HTMLelement("input") }}, {{ HTMLelement("map") }}, {{ HTMLelement("meta") }}, {{ HTMLelement("object") }}, {{ HTMLelement("param") }}, {{ HTMLelement("select") }}, and {{ HTMLelement("textarea") }}.</p> + +<div class="note"> +<p>需要注意的是,<code>name</code> 属性在其他类型元素上不存在。它不是 {{domxref("Element")}} 或 {{domxref("HTMLElement")}} 接口的一个属性。</p> +</div> + +<p>Name 可被使用于 {{ domxref("document.getElementsByName()") }} 方法,<a href="/en/DOM/HTMLFormElement" title="en/DOM/form">form</a> 以及 the form <a href="/en/DOM/form.elements" title="en/DOM/form.elements">elements</a> collection。当使用于表单(form)或表单元素(form elements collection)时,可能返回一个单独的元素或一个元素集合。</p> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="eval"><em>HTMLElement</em>.name = <em>string</em>; +var elName = <em>HTMLElement</em>.name; + +var fControl = <em>HTMLFormElement</em>.<em>elementName</em>; +var controlCollection = <em>HTMLFormElement</em>.elements.<em>elementName</em>; +</pre> + +<h2 id="Example" name="Example">例子</h2> + +<pre class="eval"><form action="" name="formA"> + <input type="text" value="foo"> +</form> + +<script type="text/javascript"> + + // 获取表单中第一个元素的引用 + var formElement = document.forms['formA'].elements[0]; + + // 设置一个 name + formElement.name = 'inputA'; + + // 显示 input 的 value 值 + alert(document.forms['formA'].elements['inputA'].value); + +</script> +</pre> + +<h2 id="Notes" name="Notes">备注</h2> + +<p>在 IE6 中,使用 {{domxref("document.createElement()")}} 方法创建的 DOM 对象的 name 属性不能被更改。</p> + +<h2 id="Specification" name="Specification">规范</h2> + +<p>W3C DOM 2 HTML Specification:</p> + +<ul> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-32783304">Anchor</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-39843695">Applet</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-34812697">Button</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-22051454">Form</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-91128709">Frame</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-96819659">iFrame</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-47534097">Image</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-89658498">Input</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-52696514">Map</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-31037081">Meta</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-20110362">Object</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-59871447">Param</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-41636323">Select</a></li> + <li><a class="external" href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-70715578">Textarea</a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html b/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html new file mode 100644 index 0000000000..fb69717e99 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html @@ -0,0 +1,44 @@ +--- +title: event.altKey +slug: Web/API/event.altKey +translation_of: Web/API/MouseEvent/altKey +translation_of_original: Web/API/event.altKey +--- +<p>{{ ApiRef() }}</p> +<h3 id="Summary" name="Summary">概述</h3> +<p>表明当事件触发时,ALT键是否处于按下的状态.</p> +<h3 id="Syntax" name="Syntax">语法</h3> +<pre class="eval">event.altKey +</pre> +<h3 id="例子">例子</h3> +<pre><code><em>var bool</em> = event.altKey;</code> +</pre> +<p>如果当事件触发时,ALT键处于按下的状态,<code style="font-family: 'Courier New','Andale Mono',monospace; font-style: normal; font-variant: normal; font-size: 100%; line-height: normal; color: inherit; font-weight: inherit;">则bool</code>的值为<code style="font-family: 'Courier New','Andale Mono',monospace; font-style: normal; font-variant: normal; font-size: 100%; line-height: normal; color: inherit; font-weight: inherit;">true,否则为</code><code style="font-family: 'Courier New','Andale Mono',monospace; font-style: normal; font-variant: normal; font-size: 100%; line-height: normal; color: inherit; font-weight: inherit;">false</code>.</p> +<pre class="brush: html"><html> +<head> +<title>altKey 示例</title> + +<script type="text/javascript"> + +function showChar(e){ + alert( + "按下的键: " + String.fromCharCode(e.charCode) + "\n" + + "charCode: " + e.charCode + "\n" + + "是否按下ALT键: " + e.altKey + "\n" + ); +} + +</script> +</head> + +<body onkeypress="showChar(event);"> +<p> +按下一个字符键,尝试同时按下ALT键.<br /> +你也可以同时按下SHIFT键和ALT键. +</p> +</body> +</html> +</pre> +<h3 id="规范">规范</h3> +<p>DOM Level 2 Events - property of MouseEvent object</p> +<p>{{ languages( { "ja": "ja/DOM/event.altKey", "pl": "pl/DOM/event.altKey", "en": "en/DOM/event.altKey" } ) }}</p> diff --git a/files/zh-cn/conflicting/web/api/mouseevent/button/index.html b/files/zh-cn/conflicting/web/api/mouseevent/button/index.html new file mode 100644 index 0000000000..c75916a287 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/mouseevent/button/index.html @@ -0,0 +1,82 @@ +--- +title: event.button +slug: Web/API/event.button +translation_of: Web/API/MouseEvent/button +translation_of_original: Web/API/event.button +--- +<p>{{ ApiRef() }}</p> +<h3 id="Summary" name="Summary">概述</h3> +<p>表明当前事件是由鼠标的哪个按键触发的.</p> +<h3 id="Syntax" name="Syntax">语法</h3> +<pre>event.button +</pre> +<h3 id="例子">例子</h3> +<pre>var buttonCode = event.button; +</pre> +<p>该属性返回一个整数值,代表触发当前事件的鼠标按键.在通常情况下,对应关系如下:</p> +<ul> + <li>0 为 左键点击.</li> + <li>1 为 中键点击.</li> + <li>2 为 右键点击.</li> +</ul> +<div class="note"> + <strong>注意:</strong> IE不遵守 See <a class="external" href="http://www.quirksmode.org/js/events_properties.html#button" title="http://www.quirksmode.org/js/events_properties.html#button">QuirksMode for details</a>.</div> +<p>The order of buttons may be different depending on how the pointing device has been configured.</p> +<h3 id="Example" name="Example">例子</h3> +<pre class="brush: html"><script> +var whichButton = function (e) { + // 处理不同的事件模型 + var e = e || window.event; + var btnCode; + + if ('object' === typeof e) { + btnCode = e.button; + + switch (btnCode) { + case 0: + alert('你按了左键.'); + break; + case 1: + alert('你按了中键.'); + break; + case 2: + alert('你按了右键.'); + break; + default: + alert('未知按键: ' + btnCode); + } + } +} +</script> + +<button onmouseup="whichButton(event);" oncontextmenu="event.preventDefault();">请点击鼠标...</button> +</pre> +<h3 id="Notes" name="Notes">备注</h3> +<p>Because mouse clicks are frequently intercepted by the user interface, it may be difficult to detect buttons other than those for a standard mouse click (usually the left button) in some circumstances.</p> +<p>Users may change the configuration of buttons on their pointing device so that if an event's button property is zero, it may not have been caused by the button that is physically left–most on the pointing device; however, it should behave as if the left button was clicked in the standard button layout.</p> +<h3 id="Specification" name="Specification">规范</h3> +<p>DOM 2 Events Specification: <a class="external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent-button">button</a></p> +<h3 id="浏览器兼容性">浏览器兼容性</h3> +<p>Based on Jan Wolter's <a class="external" href="http://unixpapa.com/js/mouse.html">JavaScript Madness: Mouse Events</a>.</p> +<p>{{ CompatibilityTable() }}</p> +<div id="compat-desktop"> + <table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Gecko</th> + <th>Webkit</th> + <th>Internet Explorer</th> + <th>Opera</th> + </tr> + <tr> + <td>Basic support</td> + <td>1</td> + <td>523</td> + <td>9</td> + <td>8</td> + </tr> + </tbody> + </table> +</div> +<p>{{ languages( { "ja": "ja/DOM/event.button", "pl": "pl/DOM/event.button" ,"en": "en/DOM/event.button" } ) }}</p> diff --git a/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html b/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html new file mode 100644 index 0000000000..a334f4b2eb --- /dev/null +++ b/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html @@ -0,0 +1,124 @@ +--- +title: event.relatedTarget +slug: Web/API/event.relatedTarget +translation_of: Web/API/MouseEvent/relatedTarget +translation_of_original: Web/API/event.relatedTarget +--- +<h2 id="Summary" name="Summary"> </h2> + +<p>{{APIRef("DOM")}}</p> + +<h2 id="Summary" name="Summary">简要</h2> + +<p>为事件标识第二目标</p> + +<h2 id="Summary" name="Summary">描述</h2> + +<p><code>relatedTarget</code> 属性用于在一个事件中查找另外一个元素。有些事件比如 <code>mouseover</code> 通常侧重处理一个特定的目标,而有些有也可能会涉及到第二目标,比如当目标退出第一目标的 <code>mouseover</code> 事件.</p> + +<h2 id="事件">事件</h2> + +<p>只有 <code>MouseEvent</code>s 有这个属性,而且这些些只在特定的 <code>MouseEvent</code>s 事件中有效:</p> + +<table class="standard-table" style="width: auto;"> + <tbody> + <tr> + <td class="header">事件名</td> + <td class="header"><code>relatedTarget</code> role</td> + </tr> + <tr> + <td>focusin</td> + <td>哪个 {{domxref("EventTarget")}} 失去焦点</td> + </tr> + <tr> + <td>focusout</td> + <td>哪个 {{domxref("EventTarget")}} 获得焦点</td> + </tr> + <tr> + <td>mouseenter</td> + <td>鼠标从哪个 {{domxref("EventTarget")}} 进来</td> + </tr> + <tr> + <td>mouseleave</td> + <td>鼠标移到哪个{{domxref("EventTarget")}} 去</td> + </tr> + <tr> + <td>mouseout</td> + <td>鼠标移到哪个{{domxref("EventTarget")}} 去</td> + </tr> + <tr> + <td>mouseover</td> + <td>鼠标从哪个{{domxref("EventTarget")}} 进来</td> + </tr> + <tr> + <td>dragenter</td> + <td>鼠标从哪个{{domxref("EventTarget")}} 进来</td> + </tr> + <tr> + <td>dragexit</td> + <td>鼠标移到哪个{{domxref("EventTarget")}} 去</td> + </tr> + </tbody> +</table> + +<h2 id="Example" name="Example">示例</h2> + +<pre class="brush: html"><!DOCTYPE html> +<html> +<head> + +<style> +div > div { + height: 128px; + width: 128px; +} +#top { background-color: red; } +#bottom { background-color: blue; } +</style> + +<script> +function outListener(event) { + console.log("exited " + event.target.id + " for " + event.relatedTarget.id); +} + +function overListener(event) { + console.log("entered " + event.target.id + " from " + event.relatedTarget.id); +} + +function loadListener() { + var top = document.getElementById("top"), + bottom = document.getElementById("bottom"); + + top.addEventListener("mouseover", overListener); + top.addEventListener("mouseout", outListener); + bottom.addEventListener("mouseover", overListener); + bottom.addEventListener("mouseout", outListener); +} +</script> + +</head> + +<body onload="loadListener();"> + +<div id="outer"> + <div id="top"></div> + <div id="bottom"></div> +</div> + +</body> +</html> +</pre> + +<p><a href="https://jsfiddle.net/uTe99">在JSFiddle中查看</a></p> + +<h2 id="Specification" name="Specification">Specification</h2> + +<ul> + <li><a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent-relatedTarget">DOM Level 2 Events: MouseEvent.relatedTarget</a></li> +</ul> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/DOM/event/Comparison_of_Event_Targets" title="DOM/event/Comparison_of_Event_Targets">Comparison of Event Targets</a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html b/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html new file mode 100644 index 0000000000..e01246caca --- /dev/null +++ b/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html @@ -0,0 +1,41 @@ +--- +title: event.shiftKey +slug: Web/API/event.shiftKey +translation_of: Web/API/MouseEvent/shiftKey +translation_of_original: Web/API/event.shiftKey +--- +<p>{{ ApiRef() }}</p> +<h3 id="Summary" name="Summary">概述</h3> +<p>表明当事件触发时,SHIFT键是否处于按下状态.</p> +<h3 id="Syntax" name="Syntax">语法</h3> +<pre class="eval"><em>var bool</em> = event.shiftKey; +</pre> +<p><code>bool</code> 的值为 <code>true</code> 或 <code>false</code></p> +<h3 id="Example" name="Example">例子</h3> +<pre><html> +<head> +<title>shiftKey example</title> + +<script type="text/javascript"> + +function showChar(e){ + alert( + "Key Pressed: " + String.fromCharCode(e.charCode) + "\n" + + "charCode: " + e.charCode + "\n" + + "SHIFT key pressed: " + e.shiftKey + "\n" + + "ALT key pressed: " + e.altKey + "\n" + ); +} + +</script> +</head> + +<body onkeypress="showChar(event);"> +<p><span>按下一个字符键,尝试同时按下</span>SHIFT<span>键.</span><br /> +<span>你也可以同时按下SHIFT键和ALT键.</span></p> +</body> +</html> +</pre> +<h3 id="Specification" name="Specification">规范</h3> +<p><a class="external" href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-MouseEvent-shiftKey">shiftKey </a></p> +<p>{{ languages( { "pl": "pl/DOM/event.shiftKey" ,"en": "en/DOM/event.shiftKey" } ) }}</p> diff --git a/files/zh-cn/conflicting/web/api/node/getrootnode/index.html b/files/zh-cn/conflicting/web/api/node/getrootnode/index.html new file mode 100644 index 0000000000..6291ef7fd6 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/node/getrootnode/index.html @@ -0,0 +1,115 @@ +--- +title: Node.rootNode +slug: Web/API/Node/rootNode +tags: + - API + - DOM + - Node + - Property + - Reference + - rootNode +translation_of: Web/API/Node/getRootNode +translation_of_original: Web/API/Node/rootNode +--- +<p>{{deprecated_header}}{{APIRef("DOM")}}{{SeeCompatTable}}</p> + +<p><code><strong>Node.rootNode</strong></code> 是 {{domxref("Node")}} 的一个只读属性, 返回该节点所在 DOM 数的根节点(最高节点). 此属性是通过 {{domxref("Node.parentNode")}} 属性循环查找直到找到根节点.</p> + +<div class="warning"> +<p><strong>注意</strong>: 由于某种原因, 此属性已经被 {{domxref("Node.getRootNode()")}} 方法替代.</p> +</div> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre><var>rootNode</var> = <em>node</em>.rootNode; +</pre> + +<h3 id="返回值"> 返回值</h3> + +<p>返回 {{domxref("Node")}} 对象.</p> + +<h2 id="Example" name="Example">样例</h2> + +<p>下面是输出<code>body</code>的根节点样例:</p> + +<pre class="brush: js">console.log(document.body.rootNode);</pre> + +<h2 id="Notes" name="Notes">参考</h2> + +<p></p><p>Gecko内核的浏览器会在源代码中标签内部有空白符的地方插入一个文本结点到文档中.因此,使用诸如 + <a href="/zh-CN/docs/Web/API/Node/firstChild" title="Node.firstChild 只读属性返回树中节点的第一个子节点,如果节点是无子节点,则返回 null。"><code>Node.firstChild</code></a> 和 <a href="/zh-CN/docs/Web/API/Node/previousSibling" title="返回当前节点的前一个兄弟节点,没有则返回null."><code>Node.previousSibling</code></a> 之类的方法可能会引用到一个空白符文本节点, + 而不是使用者所预期得到的节点.</p> + + <p>详情请参见 <a class="new" href="/zh-CN/docs/Whitespace_in_the_DOM" rel="nofollow">DOM 中的空白符</a> + 和<a class="external" href="http://www.w3.org/DOM/faq.html#emptytext" rel="noopener">W3C DOM 3 FAQ: 为什么一些文本节点是空的</a>.</p><p></p> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}<sup>[1]</sup></td> + <td>{{CompatNo}}<sup>[1]</sup></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatNo}}<sup>[1]</sup></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatNo}}<sup>[1]</sup></td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<p>[1] 此属性已经废弃, 使用{{domxref("Node.getRootNode()")}} 方法替代.</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">规范</th> + <th scope="col">样式</th> + <th scope="col">备注</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('DOM WHATWG', '#dom-node-rootnode', 'Node.rootNode')}}</td> + <td>{{Spec2('DOM WHATWG')}}</td> + <td>初始定义</td> + </tr> + </tbody> +</table> diff --git a/files/zh-cn/conflicting/web/api/node/index.html b/files/zh-cn/conflicting/web/api/node/index.html new file mode 100644 index 0000000000..ad04356656 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/node/index.html @@ -0,0 +1,19 @@ +--- +title: Node.baseURIObject +slug: Web/API/Node/baseURIObject +translation_of: Web/API/Node +translation_of_original: Web/API/Node/baseURIObject +--- +<div> + {{ApiRef}} {{Fx_minversion_header("3")}} {{Non-standard_header}}</div> +<h2 id="Summary" name="Summary">概述</h2> +<p><code>baseURIObject</code>属性返回一个代表当前节点(通常是文档节点或元素节点)的基URL的{{Interface("nsIURI")}}对象.该属性类似与{{domxref("Node.baseURI")}},只是它返回的是一个包含更多信息的nsIURI对象,而不只是一个URL字符串.</p> +<p>该属性在所有类型的节点上都可用(HTML,XUL,SVG,MathML等),但脚本本身必须要有 UniversalXPConnect权限(XUL默认有这个权限,HTML没有).</p> +<p>查看{{domxref("Node.baseURI")}}了解基URL(base URL)是什么.</p> +<h2 id="Syntax" name="Syntax">语法</h2> +<pre class="syntaxbox"><var>uriObj</var> = <em>node</em>.baseURIObject +</pre> +<h2 id="Notes" name="Notes">附注</h2> +<p>该属性只读,尝试为它赋值会抛出异常. 此外,这个属性只能从特权代码中访问.</p> +<h2 id="Specification" name="Specification">规范</h2> +<p>不属于任何规范,mozilla私有属性.</p> diff --git a/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html b/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html new file mode 100644 index 0000000000..58844aef2e --- /dev/null +++ b/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html @@ -0,0 +1,19 @@ +--- +title: Node.nodePrincipal +slug: Web/API/Node/nodePrincipal +translation_of: Web/API/Node +translation_of_original: Web/API/Node/nodePrincipal +--- +<div> + {{APIRef}}{{Fx_minversion_header(3)}}{{Non-standard_header}} + <p>The <code><strong>Node.nodePrincipal</strong></code> read-only property returns the {{Interface("nsIPrincipal")}} object representing current security context of the node.</p> + <p>{{Note("This property exists on all nodes (HTML, XUL, SVG, MathML, etc.), but only if the script trying to use it has chrome privileges.")}}</p> + <h2 id="Syntax" name="Syntax">Syntax</h2> + <pre class="syntaxbox"><i>principalObj</i> = element.nodePrincipal +</pre> + <h2 id="Notes" name="Notes">Notes</h2> + <p>This property is read-only; attempting to write to it will throw an exception. In addition, this property may only be accessed from privileged code.</p> + <h2 id="Specification" name="Specification">Specification</h2> + <p>Not in any specification.</p> +</div> +<p> </p> diff --git a/files/zh-cn/conflicting/web/api/push_api/index.html b/files/zh-cn/conflicting/web/api/push_api/index.html new file mode 100644 index 0000000000..e616d4e12d --- /dev/null +++ b/files/zh-cn/conflicting/web/api/push_api/index.html @@ -0,0 +1,424 @@ +--- +title: Using the Push API +slug: Web/API/Push_API/Using_the_Push_API +tags: + - Push + - Push API + - Service Workers + - Using the Push API +translation_of: Web/API/Push_API +translation_of_original: Web/API/Push_API/Using_the_Push_API +--- +<p class="summary"><span>W3C <a href="/en-US/docs/Web/API/Push_API">Push API</a> </span>为开发人员在Web应用程序中提供了一些令人兴奋的新功能:本文提供了一个简单的演示,以获取Push通知的设置和运行。</p> + +<p>在任何时候——不论这一应用是否处于激活状态——从服务器向客户端推送消息或者通知的能力,是一种原生应用已经享受了一段时间的能力。现在 Web 应用也拥有了这一能力。桌面系统上的 Firefox 43+ 和 Chrome 42+ 已经支持 Push 的大部分功能,移动平台也很可能在不久的将来提供支持。 {{domxref("PushMessageData")}} 当前只在 Firefox Nightly (44+) 中提供实验性的支持,并且这一实现也可能会变更。</p> + +<div class="note"> +<p><strong>Note</strong>: Firefox OS 的早期版本使用了这一 API 的一个 proprietary 版本,叫做 <a href="/en-US/docs/Web/API/Simple_Push_API">Simple Push</a> ,现在已经被 Push API 标准废弃。</p> +</div> + +<h2 id="Demo_the_basis_of_a_simple_chat_server_app">Demo: the basis of a simple chat server app</h2> + +<p>我们创建的这一 demo 是一个简单的聊天应用。它提供了一个表单,用来输入聊天内容,还有一个按钮,用来订阅(subscribe)推送的消息。按下按钮后,你将订阅这一消息推送服务,服务器会记录你的信息,同时当前所有的订阅者会收到一个推送消息,告诉他们有人订阅。</p> + +<p>此时,新订阅者的名字会出现在订阅者列表上,同时界面上会出现一个文本域和一个提交按钮,允许订阅者发送消息。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11823/push-api-demo.png" style="border: 1px solid black; display: block; height: 406px; margin: 0px auto; width: 705px;"></p> + +<p>要运行这一 demo,请参阅 <a href="https://github.com/chrisdavidmills/push-api-demo">push-api-demo README</a>。请注意,想要在 Chrome 中使用这一应用并且以一个更合理的方式运行,服务器端还需要大量的工作。然而,推送的细节解释起来特别麻烦,我们先概览这个推送接口是怎么运作的,然后再回来详细了解。</p> + +<h2 id="Technology_overview">Technology overview</h2> + +<p>这一部分提供了这一例子中用到的技术的概览。</p> + +<p>Web Push 消息是 <a href="/en-US/docs/Web/API/Service_Worker_API">service workers</a> 技术族的一部分;特别的,一个service worker想要接收消息,就必须在一个页面上被激活。 在 service worker 接收到推送的消息后,你可以决定如何显示这一消息。你可以:</p> + +<ul> + <li>发送一个 <a href="/en-US/docs/Web/API/Notifications_API">Web notification</a> ,弹出一个系统通知提醒用户。这一操作需要发送推送消息的权限。</li> + <li>通过 {{domxref("MessageChannel")}} 将消息送回主页面。</li> +</ul> + +<p>通常这两者可以结合使用,下面的 demo 显示了两者的特点。</p> + +<div class="note"> +<p><span style="font-size: 14px;"><strong>注:</strong>你需要在服务器端部署某种形式的代码来处理endpoint数据的加密和发送推送消息的请求。</span> 在我们的Demo里,我们把那些代码放进了一个快速、劣质的服务器代码(a quick-and-dirty server )里,部署在 <a href="https://nodejs.org/">NodeJS</a> 上。</p> +</div> + +<p>service worker 需要订阅推送消息服务。在订阅服务时,每一个会话会有一个独立的端点(endpoint)。订阅对象的属性({{domxref("PushSubscription.endpoint")}}) 即为端点值。将端点发送给服务器后,服务器用这一值来发送消息给会话的激活的 service worker。不同浏览器需要用不同的推送消息服务器。</p> + +<h3 id="加密(Encryption)">加密(Encryption)</h3> + +<div class="note"> +<p><strong>Note</strong>: For an interactive walkthrough, try JR Conlin's <a href="https://jrconlin.github.io/WebPushDataTestPage/">Web Push Data Encryption Test Page</a>.</p> +</div> + +<p>在通过推送消息发送数据时,数据需要进行加密。数据加密需要通过 {{domxref("PushSubscription.getKey()")}} 方法产生的一个公钥。这一方法在服务器端运行,通过复杂的密码学机制来生成公钥,详情可参阅 <a href="https://tools.ietf.org/html/draft-ietf-webpush-encryption-01">Message Encryption for Web Push</a> 。以后可能会有更多用于处理推送消息加密的库出现,在这一 demo 中,我们使用 Marco Castelluccio's NodeJS <a href="https://github.com/marco-c/web-push">web-push library</a>.</p> + +<div class="note"> +<p><strong>Note</strong>: There is also another library to handle the encryption with a Node and Python version available, see <a href="https://github.com/martinthomson/encrypted-content-encoding">encrypted-content-encoding</a>.</p> +</div> + +<h3 id="Push_workflow_summary">Push workflow summary</h3> + +<p>这里我们总结一下推送消息的实现。在之后的章节中你可以找到这一 demo 代码的更多细节。</p> + +<ol> + <li>请求 web 通知及你所使用的其他功能的权限。</li> + <li>调用 {{domxref("ServiceWorkerContainer.register()")}} ,注册一个 service worker。</li> + <li>使用 {{domxref("PushManager.subscribe()")}} 订阅推送消息。</li> + <li>取得与订阅相关联的 endpoint ({{domxref("PushSubscription.endpoint")}}),并且生成一个客户公钥({{domxref("PushSubscription.getKey()")}}) 。注意 <code>getKey()</code> 是试验性的,只在 Firefox 有效。</li> + <li>将详细信息发送给服务器,服务器可以用这些信息来发送推送消息。这一 demo 使用 {{domxref("XMLHttpRequest")}} ,但你也可以使用 <a href="/en-US/docs/Web/API/Fetch_API">Fetch</a> 。</li> + <li>如果你使用 <a href="/en-US/docs/Web/API/Channel_Messaging_API">Channel Messaging API</a> 来和 service worker 通信,则创建一个新的 message channel ({{domxref("MessageChannel.MessageChannel()")}}) ,并且在 service worker 调用 {{domxref("Worker.postMessage()")}} ,将 <code>port2</code> 发送给 service worker ,以建立 communication channel 。你应该设置一个 listener 来响应从 service worker 发来的消息。</li> + <li>在服务器端,存储端点以及其他在发送推送消息给订阅者时需要的信息(我们使用一个简单的文本文件,但你可以使用数据库,或者其他你喜欢的方式)。在生产环境中,请保护好这些信息,以防恶意的攻击者用这些信息给订阅者推送垃圾消息。</li> + <li>要发送一个推送消息,你需要向端点 URL 发送一个 HTTP <code>POST</code> 。这一请求需要包括一个 TTL 头,用来规定用户离线时消息队列的最大长度。要在请求中包括数据,你需要使用客户公钥进行加密。在我们的 demo 中,我们使用 <a href="https://github.com/marco-c/web-push">web-push</a> 模块来处理困难的部分。</li> + <li>在你的 service worker 中,设置一个 <code>push</code> 事件句柄来响应接收到的推送消息。 + <ol> + <li>如果你想要将一个信道消息发送回主 context(看第6步),你需要先取得之前发送给 service worker 的 <code>port2</code> 的引用 ({{domxref("MessagePort")}}) 。这个可以通过传给 <code>onmessage</code> handler ({{domxref("ServiceWorkerGlobalScope.onmessage")}}) 的{{domxref("MessageEvent")}} 对象取得。 具体地说,是 <code>ports</code> 属性的索引 0 。 之后你可以用 {{domxref("MessagePort.postMessage()")}} 来向 <code>port1</code> 发送消息 。</li> + <li>如果你想要使用系统通知,可以调用 {{domxref("ServiceWorkerRegistration.showNotification()")}} 。注意,在我们的代码中,我们将其运行在一个 {{domxref("ExtendableEvent.waitUntil()")}} 方法中——这样做将事件的 生命周期(lifetime)扩展到了通知被处理后,使得我们可以确认事情像我们期望的那样进行。<span id="cke_bm_307E" style="display: none;"> </span></li> + </ol> + </li> +</ol> + +<h2 id="Building_up_the_demo">Building up the demo</h2> + +<p>让我们浏览一下 demo 的代码,理解一下它是如何工作的。</p> + +<h3 id="The_HTML_and_CSS">The HTML and CSS</h3> + +<p>这个 demo 的 HTML 和 CSS 没有什么需要特别留意的地方。初始化时,HTML包含一个简单的表单、一个按钮和两个列表。按钮用来订阅,两个列表分别显示订阅者和聊天消息。订阅之后,会出现用来输入聊天消息的控件。</p> + +<p>为了对不干扰 Push API 的理解,CSS被设计得非常简单。</p> + +<h3 id="The_main_JavaScript_file">The main JavaScript file</h3> + +<p>JavaScript 明显更加重要。让我们看看主 JS 文件。</p> + +<h4 id="Variables_and_initial_setup">Variables and initial setup</h4> + +<p>开始时,我们声明一些需要使用的变量:</p> + +<pre class="brush: js">var isPushEnabled = false; +var useNotifications = false; + +var subBtn = document.querySelector('.subscribe'); +var sendBtn; +var sendInput; + +var controlsBlock = document.querySelector('.controls'); +var subscribersList = document.querySelector('.subscribers ul'); +var messagesList = document.querySelector('.messages ul'); + +var nameForm = document.querySelector('#form'); +var nameInput = document.querySelector('#name-input'); +nameForm.onsubmit = function(e) { + e.preventDefault() +}; +nameInput.value = 'Bob';</pre> + +<p>首先,是两个布尔变量,一个用来记录 Push 是否被订阅,一个用来记录是否有通知的权限。</p> + +<p>其次,是订阅/取消订阅 {{htmlelement("button")}} 的引用,以及发送消息按钮的引用和输入的引用(订阅成功之后按钮和输入才会创建)。</p> + +<p>接下来,是页面上的三个{{htmlelement("div")}} 元素的引用,在需要插入元素时会用到(比如创建 <em>Send Chat Message</em> 按钮,或者 <em>Messages </em>列表中增加聊天消息时)。</p> + +<p>最后,是 name selection 表单和 {{htmlelement("input")}} 元素的引用。我们给 input 一个默认值,并且使用 <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code> 方法,让按下回车时不会自动提交表单。</p> + +<p>之后,我们通过 {{domxref("Notification.requestPermission","requestPermission()")}} 请求发送web通知的权限:</p> + +<pre class="brush: js">Notification.requestPermission();</pre> + +<p>在 <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onload">onload</a></code> 时我们运行一段代码,让应用开始初次加载时的初始化过程。首先我们给 subscribe/unsubscribe 按钮添加 click event listener ,让这一按钮在已经订阅(<code>isPushEnabled为真)</code>时执行 <code>unsubscribe()</code> 函数,否则执行 <code>subscribe()</code> :</p> + +<pre class="brush: js">window.addEventListener('load', function() { + subBtn.addEventListener('click', function() { + if (isPushEnabled) { + unsubscribe(); + } else { + subscribe(); + } + });</pre> + +<p>之后,我们检查 service workers 是否被支持。如果支持,则用 {{domxref("ServiceWorkerContainer.register()")}} 注册一个 service worker 并且运行 <code>initialiseState()</code> 函数。若不支持,则向控制台输出一条错误信息。</p> + +<pre class="brush: js"> // Check that service workers are supported, if so, progressively + // enhance and add push messaging support, otherwise continue without it. + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('sw.js').then(function(reg) { + if(reg.installing) { + console.log('Service worker installing'); + } else if(reg.waiting) { + console.log('Service worker installed'); + } else if(reg.active) { + console.log('Service worker active'); + } + + initialiseState(reg); + }); + } else { + console.log('Service workers aren\'t supported in this browser.'); + } +}); +</pre> + +<p>接下来是 <code>initialiseState()</code> 函数。查看 <a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/main.js"><code>initialiseState()</code> source on Github</a> 可获得有注释的完整源码(简洁起见,此处省略)。</p> + +<p><code>initialiseState()</code> 首先检查 service workers 是否支持 notifications ,如果支持则将 <code>useNotifications</code> 变量设为真。之后检查用户是否允许 said notifications , push messages 是否支持,并分别进行设置。</p> + +<p>最后,使用 {{domxref("ServiceWorkerContainer.ready()")}} 来检测 service worker 是否被激活并开始运行,会返回一个Promise对象。当这一 promise 对象 resolve 时,我们访问 {{domxref("ServiceWorkerRegistration.pushManager")}} 属性,得到一个 {{domxref("PushManager")}} 对象,再调用该对象的 {{domxref("PushManager.getSubscription()")}}方法,最终获得用来推送消息的订阅对象。当第二个 promise 对象 resolve 时,我们启用 subscribe/unsubscribe 按钮(<code>subBtn.disabled = false;)</code>,并确认订阅对象。</p> + +<p>这样做了之后,订阅的准备工作已经完成了。即使这一应用并没有在浏览器中打开, service worker 也依然可能在后台处于激活状态。如果我们已经订阅,则对UI进行更新,修改按钮的标签,之后将 <code>isPushEnabled 设为真,通过 </code>{{domxref("PushSubscription.endpoint")}} 取得订阅的端点,通过 {{domxref("PushSubscription.getKey()")}} 生成一个公钥,调用<code> updateStatus()</code> 方法与服务器进行通信。</p> + +<p>此外,我们通过 {{domxref("MessageChannel.MessageChannel()")}} 得到一个新的 {{domxref("MessageChannel")}} 对象,并通过 {{domxref("ServiceworkerRegistration.active")}} 得到一个激活的 service worker 的引用,然后通过 {{domxref("Worker.postMessage()")}} 在主浏览器 context 和 service worker 间建立起一个信道。浏览器 context 接收 {{domxref("MessageChannel.port1")}} 中的消息。当有消息到来时,我们使用 <code>handleChannelMessage()</code> 方法来决定如何处理数据(参阅{{anch("Handling channel messages sent from the service worker")}})。</p> + +<h4 id="订阅和取消订阅(Subscribing_and_unsubscribing)">订阅和取消订阅(Subscribing and unsubscribing)</h4> + +<p>现在把我们的注意力转到 <code>subscribe()</code> 和 <code>unsubscribe()</code> 函数上,它们用来订阅或取消订阅 来自服务器的通知。</p> + +<p>在订阅的时候,我们使用 {{domxref("ServiceWorkerContainer.ready()")}}方法再一次确认service worker处于激活状态并且可以使用了。当 promise 成功执行,我们用{{domxref("PushManager.subscribe()")}}方法订阅服务。如果订阅成功,我们会得到一个 {{domxref("PushSubscription")}} 对象,它携带了endpoint信息 ,并且可以产生(generate)一个公钥的方法 (再多说一点,{{domxref("PushSubscription.endpoint")}}属性和{{domxref("PushSubscription.getKey()")}}方法),我们要把这两个信息传递给<code>updateStatus()</code> 函数,同时还要传递第三个信息——更新状态的类型(订阅还是不订阅),让它能够把这些必要的细节传递给服务器。</p> + +<p>我们也需要更新我们应用的状态 (设置 <code>isPushEnabled</code> 为<code>true</code>) 和 UI (激活<strong>订阅</strong>或者不订阅的按钮,同时改变标签的显示状态,让用户下一次点击按钮的时候变成<strong>不订阅</strong>的状态或者订阅的状态。)</p> + +<p><code><font face="Open Sans, Arial, sans-serif">不订阅 </font>unsubscribe()</code> 函数在结构上和订阅函数相识,然而基本上它们做的是完全相反的事; 最值得注意的不同是得到当前订阅对象是使用{{domxref("PushManager.getSubscription()")}}方法,而且使用{{domxref("PushSubscription.unsubscribe()")}}方法获得的promise对象。</p> + +<p>在两个函数中也提供了适当的错误处理函数。</p> + +<p><code><font face="Open Sans, Arial, sans-serif">为了节省时间,我们只在下面展示</font>subscribe()的代码;</code>查看全部请点击 <a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/main.js">subscribe/unsubscribe code on Github</a>.</p> + +<pre class="brush: js">function subscribe() { + // Disable the button so it can't be changed while + // we process the permission request + + subBtn.disabled = true; + + navigator.serviceWorker.ready.then(function(reg) { + reg.pushManager.subscribe({userVisibleOnly: true}) + .then(function(subscription) { + // The subscription was successful + isPushEnabled = true; + subBtn.textContent = 'Unsubscribe from Push Messaging'; + subBtn.disabled = false; + + // Update status to subscribe current user on server, and to let + // other users know this user has subscribed + var endpoint = subscription.endpoint; + var key = subscription.getKey('p256dh'); + updateStatus(endpoint,key,'subscribe'); + }) + .catch(function(e) { + if (Notification.permission === 'denied') { + // The user denied the notification permission which + // means we failed to subscribe and the user will need + // to manually change the notification permission to + // subscribe to push messages + console.log('Permission for Notifications was denied'); + + } else { + // A problem occurred with the subscription, this can + // often be down to an issue or lack of the gcm_sender_id + // and / or gcm_user_visible_only + console.log('Unable to subscribe to push.', e); + subBtn.disabled = false; + subBtn.textContent = 'Subscribe to Push Messaging'; + } + }); + }); +}</pre> + +<h4 id="更新应用和服务器的状态">更新应用和服务器的状态</h4> + +<p><code><font face="Open Sans, Arial, sans-serif">接下来的一个主要的JavaScript函数就是</font>updateStatus(),当订阅和取消订阅的时候,它负责更新UI中与服务器沟通的信息并发送状态更新的请求给服务器。</code></p> + +<p>这个函数做了三件事当中的哪一件事,取决于下面赋值给statusType的类型:</p> + +<ul> + <li><code>subscribe</code>: 一个按钮和和一个聊天信息的input输入框被创建后,就被插入到UI界面里面,然后通过XHR请求发送了一个包含状态信息的字面量对象给服务器,包含了statusType(subscribe)、订阅者的名字( username of the subscriber)、订阅终端(subscription endpoint)和客户端公钥(client public key)。</li> + <li><code>unsubscribe</code>: 这个和订阅基本上是相反的——聊天的按钮和输入框被移除,同时又一个字面量对象被发送给服务器,告诉它取消订阅。</li> + <li><code>init</code>: 当应用被第一次载入或者安装的时候会运行——它创建与服务器沟通的UI,并且发送一个对象告诉服务器是哪一个用户初始化(重新载入)了。</li> +</ul> + +<p>再多说一句,为了简介这里不会展示全部的代码。检查全部代码点击: <a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/main.js">full <code>updateStatus()</code> code on Github</a>.</p> + +<h4 id="处理在service_worker中发送过来的channel_message">处理在service worker中发送过来的channel message</h4> + +<p>正如刚才我们提到的,当我们接收到从service worker发送的<a href="/en-US/docs/Web/API/Channel_Messaging_API">channel message</a> 时,我们的 <code>handleChannelMessage()</code> 函数才会去执行它。 我们用{{domxref("channel.port1.onmessage")}}事件处理函数去处理{{event("message")}} event, :</p> + +<pre class="brush: js">channel.port1.onmessage = function(e) { + handleChannelMessage(e.data); +}</pre> + +<p>这个函数会在service worker中发送信息给页面的时候在页面中执行(This occurs when the <a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/sw.js#L8">service worker sends a channel message over</a>)。</p> + +<p> <code>handleChannelMessage()</code> 函数如下:</p> + +<pre class="brush: js">function handleChannelMessage(data) { + if(data.action === 'subscribe' || data.action === 'init') { + var listItem = document.createElement('li'); + listItem.textContent = data.name; + subscribersList.appendChild(listItem); + } else if(data.action === 'unsubscribe') { + for(i = 0; i < subscribersList.children.length; i++) { + if(subscribersList.children[i].textContent === data.name) { + subscribersList.children[i].parentNode.removeChild(subscribersList.children[i]); + } + } + nameInput.disabled = false; + } else if(data.action === 'chatMsg') { + var listItem = document.createElement('li'); + listItem.textContent = data.name + ": " + data.msg; + messagesList.appendChild(listItem); + sendInput.value = ''; + } +}</pre> + +<p>这个函数会做什么取决于传入的action参数的赋值:</p> + +<ul> + <li><code>subscribe</code> or <code>init</code> (在启动和重启的时候,我们需要在这个示例中做同样的事情):一个{{htmlelement("li")}} 元素被创建,它的text content 被设置为 <code>data.name</code> (订阅者的名字),然后它被添加到订阅者的列表里(一个简单的 {{htmlelement("ul")}}元素里),所以这里是订阅者(再次)加入聊天的一个视觉反馈。</li> + <li><code>unsubscribe</code>: 我们循环遍历订阅者的列表,查找谁的 text content 和<code>data.name</code> (取消订阅者的名字)相同,然后删除这个节点以提供一个视觉反馈表示有人取消订阅了。</li> + <li><code>chatMsg</code>: 和第一个表现的形式类似, 一个 {{htmlelement("li")}}被创建,它的text content设置为<code>data.name + ": " + data.msg</code> (例如: "Chris: This is my message"), 然后它被添加到每一个用户UI的聊天列表里。</li> +</ul> + +<div class="note"> +<p><span style="font-size: 14px;"><strong>注: </strong></span> 我们需要在更新DOM之前传递需要的数据给主页面(main context), 因为service worker不能操作DOM。你在使用前一定要知道service worker的一些限制。阅读 <a href="/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers">Using Service Workers</a> 获取更多细节.</p> +</div> + +<h4 id="发送聊天信息">发送聊天信息</h4> + +<p>当‘<em>Send Chat Message‘ </em>按钮被点击后,相关联的文本域的内容就作为聊天内容被发送出去。这个由 <a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/main.js"><code>sendChatMessage()</code> </a>函数处理(再多说一句,为了简洁就不展示了). 这个和 <code>updateStatus()</code> 的不同之处也是差不多的。 (查看 {{anch("Updating the status in the app and server")}}) — 我们获得 endpoint 和 public key 是来自一个 {{domxref("PushSubscription")}} 对象, 这个对象又是来自于 {{domxref("ServiceWorkerContainer.ready()")}} 方法和{{domxref("PushManager.subscribe()")}}方法。它们(endpoint、public key)被传递进一个字面量对象里面( in a message object),同时含有订阅用户的名字,聊天信息,和chatMsg的statusType,然后通过{{domxref("XMLHttpRequest")}}对象发送出去的,。</p> + +<h3 id="服务端(The_Server)">服务端(The Server)</h3> + +<p>正如我们上面提到的,我们需要一个服务端的容器去存储订阅者的信息,并且还要在状态更新时发送推送消息给客户端。 我们已经用一种hack的方式把一些需要的东西放到了一个快速-劣质(quick-and-dirty)的<a href="http://nodejs.org/">NodeJS</a> 服务端上(<code><a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/server.js">server.js</a></code>),用于处理来自客户端JavaScript的异步请求。</p> + +<p>它用一个文本文件 (<code><a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/endpoint.txt">endpoint.txt</a></code>)去存储订阅者的信息;这个文件一开始是空的(empty)。 有四种不同类型的请求,分别由被传输过来的对象中的statusType决定;这些在客户端通俗易懂的的状态类型同样也适用于服务端,因为服务端也有相同的状态。下面是这四个个状态在服务端代表的各自的含义。</p> + +<ul> + <li><code>subscribe</code>: 服务器将会添加订阅者的信息到存储的容器里 (<code><a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/endpoint.txt">endpoint.txt</a></code>),包括endpoint等,然后会推送给所有已经订阅了的订阅者一条消息,告诉每一个订阅者有新的订阅者加入了聊天。</li> + <li><code>unsubscribe</code>: 服务器在存储订阅信息的容器里找到发送该类型请求的订阅者的详情,并移除这个订阅者的信息,然后推送一条消息给所有依然订阅的用户,告诉他们这个人取消订阅了。</li> + <li><code>init</code>: 服务器从那个存储信息的文本中读取所有订阅者的信息,然后告诉他们有人初始化或者再次加入了这个聊天。</li> + <li><code>chatMsg</code>: 推送一条订阅者想发送的信息给所有的订阅者;服务器从存储容器里读取现在订阅者的信息,然后服务器给每一个人推送一条包含聊天信息的消息。</li> +</ul> + +<p>其他需要注意的东西:</p> + +<ul> + <li>我们使用的是Node.js的 <a href="https://nodejs.org/api/https.html">https 模块 </a> 去创建的服务器,因为出于安全考虑,service worker只允许工作在一个安全的连接里(https only)。这也就是为什么我们要在应用里包含了<code>.pfx</code> 安全证书,然后在Node代码里引用这个证书。</li> + <li>当你发送一条没有数据的推送消息的时候,只需要把它用http的post请求发送给对应订阅者的endpoint的URL。然而,当推送消息里包含数据的时候,你需要加密它,这个加密过程往往很复杂。随着时间的推移,一些出现的库文件(libraries)帮你做了这部分的工作。在这个demo里面我们用了 Marco Castelluccio的NodeJS库文件(<a href="https://github.com/marco-c/web-push">web-push library</a>)。查阅这些源代码了解更多加密过程是怎么完成的 (查阅 <a href="https://tools.ietf.org/html/draft-ietf-webpush-encryption-01">Message Encryption for Web Push</a> 获取更多细节)。库文件让发送一条推送消息变得简单( The library <a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/server.js#L43-L46">makes sending a push message simple</a>)。</li> +</ul> + +<h3 id="The_service_worker">The service worker</h3> + +<p>现在让我们来看看服务工作者代码(sw.js),它响应由{{Event("push")}}事件表示的推送消息。 这些通过({{domxref("ServiceWorkerGlobalScope.onpush")}})事件处理程序在服务工作人员的范围内处理; 它的工作就是为每个收到的消息做出回应。 我们首先通过调用{{domxref("PushMessageData.json()")}}将收到的消息转换回对象。然后,通过查看这个对象的action属性,就能知道这个推送消息的类型:</p> + +<ul> + <li><code>subscribe</code> 或者 <code>unsubscribe</code>: 我们发送一个系统通知是通过 <code>fireNotification()</code> 函数,但同时,也通过{{domxref("MessageChannel")}}把这个消息发送回函数的上下文环境(main context),以便我们相应地更新订阅者列表(subscriber list) (查看 {{anch("Handling channel messages sent from the service worker")}} 了解详细).</li> + <li><code>init</code> 或者 <code>chatMsg</code>: 我们只是发送一个消息回主要的上下文(main context)来处理 <code>init</code> 和 <code>chatMsg</code> 情况(这些不需要系统通知).</li> +</ul> + +<pre class="brush: js">self.addEventListener('push', function(event) { + var obj = event.data.json(); + + if(obj.action === 'subscribe' || obj.action === 'unsubscribe') { + fireNotification(obj, event); + port.postMessage(obj); + } else if(obj.action === 'init' || obj.action === 'chatMsg') { + port.postMessage(obj); + } +});</pre> + +<p>下一步, 让我们看看 <code>fireNotification()</code> 函数的代码 (它真的太他妈简单了).</p> + +<pre class="brush: js">function fireNotification(obj, event) { + var title = 'Subscription change'; + var body = obj.name + ' has ' + obj.action + 'd.'; + var icon = 'push-icon.png'; + var tag = 'push'; + + event.waitUntil(self.registration.showNotification(title, { + body: body, + icon: icon, + tag: tag + })); +}</pre> + +<p>我们先在这里列出通知消息框所需要的资源:标题、主体内容、图标。然后我们通过 {{domxref("ServiceWorkerRegistration.showNotification()")}} 方法把这个通知发送出去,同时提供一个"push"给tag属性,表示这是一个推送消息,以便我们能够在全部的通知消息中找到(identify)这个推送消息。 当我们成功发送一条推送消息,它可能会在用户对应的电脑或者设备上展示一个系统通知对话框,在不同的设备上通知对话框的外观可能是不一样的(下面的这张图片展示的是Mac OSX系统上的通知对话框)。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11855/subscribe-notification.png" style="display: block; height: 65px; margin: 0px auto; width: 326px;"></p> + +<p>注意,我们做的这些都包裹在{{domxref("ExtendableEvent.waitUntil()")}} 方法里;这是为了让ServiceWorker在发送通知消息的过程中依然保持活动,知道消息发送完成。 <code>waitUntil()</code> 会延长service worker的生命周期至(这个周期里)所有活动都已经完成。</p> + +<div class="note"> +<p><strong>Note</strong>: Web notifications from service workers were introduced around Firefox version 42, but are likely to be removed again while the surrounding functionality (such as <code>Clients.openWindow()</code>) is properly implemented (see {{bug(1203324)}} for more details.)</p> +</div> + +<h2 id="处理推送订阅过早失效(Handling_premature_subscription_expiration)">处理推送订阅过早失效(Handling premature subscription expiration)</h2> + +<p>有时候,推送订阅会过早失效,而不会调用{{domxref("PushSubscription.unsubscribe()")}} 。例如,当服务器过载或长时间处于脱机状态时,可能会发生这种情况。这是高度依赖于服务器的,所以确切的行为很难预测。 在任何情况下,您都可以通过查看{{Event("pushsubscriptionchange")}} 事件来处理此问题,您可以通过提供{{domxref("ServiceWorkerGlobalScope.onpushsubscriptionchange")}} 事件处理程序来侦听此事件;这个事件只会在这种情况下才会被触发。</p> + +<pre class="brush: js language-js"><code class="language-js">self<span class="punctuation token">.</span><span class="function token">addEventListener<span class="punctuation token">(</span></span><span class="string token">'pushsubscriptionchange'</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // do something,一般来说都会在这里重新订阅, + // 并通过XHR或者Fetch发送新的订阅信息回服务器</span><span class="comment token"> +</span><span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>注意,我们在demo里没有覆盖这种情况,因为订阅端点(subscription ending)作为一个简单的聊天服务器并不是什么难事。但是对于更复杂的示例,您可能需要重新订阅(resubscribe )用户。</p> + +<h2 id="(让Chrome支持的额外步骤)Extra_steps_for_Chrome_support">(让Chrome支持的额外步骤)Extra steps for Chrome support</h2> + +<p>为了让应用也能够在Chrome上面运行,我们需要一些额外的步骤,因为在Chrome上,现在需要依赖谷歌云消息推送(Google's Cloud Messaging) 服务才能正常工作。</p> + +<h3 id="配置谷歌云消息推送(Setting_up_Google_Cloud_Messaging)">配置谷歌云消息推送(Setting up Google Cloud Messaging)</h3> + +<p>按照以下步骤配置:</p> + +<ol> + <li>跳转到 <a href="https://console.developers.google.com">Google Developers Console</a> 然后创建一个新项目。</li> + <li>进入你项目主页(例如:我们的示例是在 <code>https://console.developers.google.com/project/push-project-978</code>), 然后 + <ol> + <li>在你的应用选项里打开<em> Google APIs </em>。</li> + <li>在下一屏,在移动API那一部分下面点击“<em>Cloud Messaging for Android</em>” 。</li> + <li>点击开启API按钮。</li> + </ol> + </li> + <li>现在你需要记下你的项目编号和API key,因为待会儿你会用到他们。 它们在这些地方: + <ol> + <li><strong>项目编号</strong>: 点击左侧的主页;项目编号在你的项目主页上方很容易看见的位置。</li> + <li><strong>API key</strong>: 点击左边菜单里的证书(<em>Credentials</em> );API key 能够在这个页面找到。</li> + </ol> + </li> +</ol> + +<h3 id="manifest.json">manifest.json</h3> + +<p>你需要在你的应用里包含Google应用风格的 <code>manifest.json</code> ,这里面的 <code>gcm_sender_id</code> 参数需要设置为你的项目编号。下面是一个简单的示例(<a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/manifest.json">manifest.json</a>):</p> + +<pre class="brush: js">{ + "name": "Push Demo", + "short_name": "Push Demo", + "icons": [{ + "src": "push-icon.png", + "sizes": "111x111", + "type": "image/png" + }], + "start_url": "/index.html", + "display": "standalone", + "gcm_sender_id": "224273183921" +}</pre> + +<p>同时,你也需要在HTML文档用一个{{HTMLElement("link")}} 标签里指向你的manifest文件:</p> + +<pre class="brush: html"><link rel="manifest" href="manifest.json"></pre> + +<h3 id="userVisibleOnly参数">userVisibleOnly参数</h3> + +<p>Chrome 要求你在订阅推送服务的时候设置 <a href="/en-US/docs/Web/API/PushManager/subscribe#Parameters"><code>userVisibleOnly 参数</code></a> 为 <code>true</code> , 表示我们承诺每当收到推送通知时都会显示通知。这可以在我们的<a href="https://github.com/chrisdavidmills/push-api-demo/blob/gh-pages/main.js#L127"> <code>subscribe()</code> 函数</a> 中看到。</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/API/Push_API">Push API</a></li> + <li><a href="/en-US/docs/Web/API/Service_Worker_API">Service Worker API</a></li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: Some of the client-side code in our Push demo is heavily influenced by Matt Gaunt's excellent examples in <a href="http://updates.html5rocks.com/2015/03/push-notificatons-on-the-open-web">Push Notifications on the Open Web</a>. Thanks for the awesome work, Matt!</p> +</div> diff --git a/files/zh-cn/conflicting/web/api/url/index.html b/files/zh-cn/conflicting/web/api/url/index.html new file mode 100644 index 0000000000..3ca38bbd39 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/url/index.html @@ -0,0 +1,105 @@ +--- +title: Window.URL +slug: Web/API/Window/URL +tags: + - Window.URL +translation_of: Web/API/URL +translation_of_original: Web/API/Window/URL +--- +<p>{{ApiRef("Window")}}{{SeeCompatTable}}</p> + +<p><strong>Window.URL</strong> 属性返回一个对象,它提供了用于创建和管理对象URLs的静态方法。它也可以作为一个构造函数被调用来构造 {{domxref("URL")}} 对象。</p> + +<div class="note"> +<p>Note: 此功能在Web Workers中可用。</p> +</div> + +<h2 id="语法">语法</h2> + +<p>调用一个静态方法:</p> + +<pre class="syntaxbox"><code><var>img</var>.src = URL.{{domxref("URL.createObjectURL", "createObjectURL")}}(<var>blob</var>);</code></pre> + +<p>构造一个新对象:</p> + +<pre class="syntaxbox"><code>var <var>url</var> = new {{domxref("URL.URL", "URL")}}("../cats/", "https://www.example.com/dogs/");</code></pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('URL', '#dom-url', 'URL')}}</td> + <td>{{Spec2('URL')}}</td> + <td>Initial definition</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>8.0<sup>[2]</sup></td> + <td>{{CompatGeckoDesktop("2.0")}}<sup>[1]</sup><br> + {{CompatGeckoDesktop("19.0")}}</td> + <td>10.0</td> + <td>15.0<sup>[2]</sup></td> + <td>6.0<sup>[2]</sup><br> + 7.0</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}<sup>[2]</sup></td> + <td>{{CompatGeckoMobile("14.0")}}<sup>[1]</sup><br> + {{CompatGeckoMobile("19.0")}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>15.0<sup>[2]</sup></td> + <td>6.0<sup>[2]</sup></td> + </tr> + </tbody> +</table> +</div> + +<p>[1] 从 Gecko 2 (Firefox 4) 到 包括Gecko 18, Gecko 返回一个不标准的nsIDOMMozURLProperty内部类型. 在实践中, 这是没有意义的.</p> + +<p>[2] 在非标准名称webkitURL下实现。</p> + +<h2 id="也可以看看">也可以看看</h2> + +<ul> + <li>{{domxref("URL")}} API.</li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/web_storage_api/index.html b/files/zh-cn/conflicting/web/api/web_storage_api/index.html new file mode 100644 index 0000000000..194b71a94a --- /dev/null +++ b/files/zh-cn/conflicting/web/api/web_storage_api/index.html @@ -0,0 +1,542 @@ +--- +title: Storage +slug: Web/Guide/API/DOM/Storage +translation_of: Web/API/Web_Storage_API +translation_of_original: Web/Guide/API/DOM/Storage +--- +<h3 id="概述"> + 概述</h3> +<p> + DOM存储是一套在<a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/" title="http://www.whatwg.org/specs/web-apps/current-work/">Web Applications 1.0</a> 规范中首次引入的与<a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#storage">存储相关的特性</a>的总称, 现在已经分离出来,单独发展成为独立的<a class="external" href="http://dev.w3.org/html5/webstorage/" title="http://dev.w3.org/html5/webstorage/">W3C Web存储</a>规范. DOM存储被设计为用来提供一个更大存储量,更安全,更便捷的存储方法,从而可以代替掉将一些不需要让服务器知道的信息存储到cookies里的这种传统方法.该特性在<a href="/zh-cn/Firefox_2_for_developers" title="zh-cn/Firefox_2_for_developers">Firefox 2</a> 和 <a class="external" href="http://developer.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Name-ValueStorage/Name-ValueStorage.html" title="http://developer.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Name-ValueStorage/Name-ValueStorage.html">Safari 4</a>中首次引入.</p> +<div class="note"> + <strong>注意:</strong> DOM存储有别于<a href="/zh-cn/Storage" title="zh-cn/Storage">mozStorage</a> (Mozilla的XPCOM接口,用来访问SQLite) 也有别于<a href="/zh-cn/Session_store_API" title="zh-cn/Session_store_API">Session store API</a> (一个<a href="/zh-cn/XPCOM" title="zh-cn/XPCOM">XPCOM</a> 存储工具,主要为扩展程序使用).</div> +<h3 id="描述"> + 描述</h3> +<p> + DOM存储的机制是通过存储字符串类型的键/值对,来提供一种安全的存取方式.这个附加功能的目标是提供一个全面的,可以用来创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间).</p> +<p> + 基于Mozilla的浏览器, Internet Explorer 8+, Safari 4+ 以及 Chrome 都提供了自己的DOM存储规范的实现. (如果你想让自己的代码兼容多个浏览器,则你需要照顾一下老版本的IE浏览器,IE下有一个类似的特性,在IE8之前版本也可以使用,叫做"<a class="external" href="http://msdn.microsoft.com/zh-cn/library/ms531424%28VS.85%29.aspx">userData behavior</a>",它允许你在多重浏览器会话中永久地保存数据.)</p> +<p> + DOM存储很有用,因为在浏览器端没有好的方法来持久保存大量数据。浏览器<a href="http://en.wikipedia.org/wiki/HTTP_cookie">cookie</a>的能力有限,而且不支持组织持久数据,其他方法(如<a href="http://www.macromedia.com/support/documentation/zh-cn/flashplayer/help/help02.html">flash本地存储</a>)需要外部插件支持。</p> +<p> + 由<a href="http://aaronboodman.com/">Aaron Boodman</a>编写的<a href="http://aaronboodman.com/halfnote/">halfnote</a>(笔记类应用程序)是第一批使用新的DOM存储功能(不包括internet explorer的userData behavior)开发的公开应用程序之一。在这个应用里,Aaron同时将笔记保存到服务器(当网络可用时)和本地,这允许使用者即使在不稳定的网络环境下也能安全的记录备注事项。</p> +<p> + 虽然halfnote的理念和实现比较简单,但是halfnote的创新展示了一种在线上和线下都可用的新型web应用的可能性。</p> +<h3 id="参考"> + 参考</h3> +<p> + 以下所提到的对象都是全局对象,作为 <a href="/zh-cn/DOM/window" title="/zh-cn/DOM/window">window 对象</a> 的属性存在。这意味着可以以 <code>sessionStorage</code> 或者 <code>window.sessionStorage 的形式访问这些对象。</code>(这点很重要,因为可以使用iframe来存储、访问除了直接包含在页面的数据之外的附加数据。)</p> +<h4 id="Storage"> + <code>Storage</code></h4> +<p> + 它是所有Storage实例(<code>sessionStorage</code>和<code>globalStorage[location.hostname]</code>)的构造函数,设置<code>Storage.prototype.removeKey = function(key) { this.removeItem(this.key(key)) }</code>,可通过<code>localStorage.removeKey</code> 和 <code>sessionStorage.removeKey</code>访问到。</p> +<p> + <code>globalStorage</code>对象不是<code>Storage</code>的实例,而是<code>StorageObsolete</code>的一个实例。</p> +<p> + <code>Storage</code>被定义在WhatWG <a class="external" href="http://dev.w3.org/html5/webstorage/#storage-0" title="http://dev.w3.org/html5/webstorage/#storage-0">Storage Interface</a> 中,如下:</p> +<pre class="eval">interface <dfn>Storage</dfn> { + readonly attribute unsigned long <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-length" title="dom-Storage-length">length</a>; + [IndexGetter] DOMString <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-key" title="dom-Storage-key">key</a>(in unsigned long index); + [NameGetter] DOMString <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-getitem" title="dom-Storage-getItem">getItem</a>(in DOMString key); + [NameSetter] void <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-setitem" title="dom-Storage-setItem">setItem</a>(in DOMString key, in DOMString data); + [NameDeleter] void <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-removeitem" title="dom-Storage-removeItem">removeItem</a>(in DOMString key); + void <a class="external" href="http://dev.w3.org/html5/webstorage/#dom-storage-clear" title="dom-Storage-clear">clear</a>(); +}; +</pre> +<div class="note"> + <strong>注意:</strong>虽然可以直接通过标准的 JavaScript 属性访问方法来设置和读取值,但是推荐的做法是使用 getItem 和 setItem 方法。</div> +<div class="note"> + <strong>注意:</strong>需要时刻注意的一点是,所有数据在被保存到下面将要介绍的任何一个存储器之前,都将通过它的 <code>.toString</code> 方法被转换成字符串。所以一个普通对象将会被存储为 <code>"[object Object]"</code>,而不是对象本身或者它的 JSON 形式。使用浏览器自身提供的 JSON 解析和序列化方法来存取对象是比较好的,也是比较常见的方法。</div> +<h4 id="sessionStorage_2"> + <code>sessionStorage</code></h4> +<p> + <code>sessionStorage</code> 是个全局对象,它维护着<span style="line-height: inherit;">在页面会话(page session)期间有效的</span><span style="line-height: inherit;">存储空间。只要浏览器开着,页面会话周期就会一直持续。当页面重新载入(reload)或者被恢复(restores)时,页面会话也是一直存在的。每在新标签或者新窗口中打开一个新页面,都会初始化一个新的会话。</span><span style="line-height: inherit;"> </span></p> +<pre class="brush: js">// 保存数据到当前会话的存储空间 +sessionStorage.setItem("username", "John"); + +// 访问数据 +alert( "username = " + sessionStorage.getItem("username")); +</pre> +<p> + 当浏览器被意外刷新的时候,一些临时数据应当被保存和恢复。<code>sessionStorage</code> 对象在处理这种情况的时候是最有用的。</p> +<p> + {{ fx_minversion_note("3.5", "在Firefox 3.5之前的版本中,如果浏览器意外崩溃,则在重启后,sessionStorage中保存的数据不会被恢复.之后的版本中,会恢复上次崩溃前的sessionStorage数据.") }}</p> +<p> + <strong>例子:</strong></p> +<p> + 自动保存一个文本域中的内容,如果浏览器被意外刷新,则恢复该文本域中的内容,所以不会丢失任何输入的数据。</p> +<pre class="brush: js"> // 获取到我们要循环保存的文本域 + var field = document.getElementById("field"); + + // 查看是否有一个自动保存的值 + // (只在浏览器被意外刷新时) + if ( sessionStorage.getItem("autosave")) { + // 恢复文本域中的内容 + field.value = sessionStorage.getItem("autosave"); + } + + // 每隔一秒检查文本域中的内容 + setInterval(function(){ + // 并将文本域的值保存到session storage对象中 + sessionStorage.setItem("autosave", field.value); + }, 1000); +</pre> +<p> + <strong>更多信息:</strong></p> +<ul> + <li> + <a class="external" href="http://dev.w3.org/html5/webstorage/#the-sessionstorage-attribute" title="http://dev.w3.org/html5/webstorage/#the-sessionstorage-attribute">sessionStorage specification</a></li> +</ul> +<h4 id="localStorage"> + <code>localStorage</code></h4> +<p> + <code>localStorage</code> is the same as sessionStorage with same same-origin rules applied but it is persistent. <code>localStorage</code> was introduced in Firefox 3.5.</p> +<div class="note"> + <strong>注意:</strong>当浏览器进入私人模式(private browsing mode,Google Chrome 上对应的应该是叫隐身模式)的时候,会创建一个新的、临时的、空的数据库,用以存储本地数据(local storage data)。当浏览器关闭时,里面的所有数据都将被丢弃。</div> +<h4 id="兼容性"> + 兼容性</h4> +<p> + 这些<code> Storage</code> 对象最近刚被加入标准当中,所以并不是所有的浏览器都支持。如果你想在没有原生支持 <code>localStorage</code> 对象的浏览器中使用它,可以在你编写的 JavaScript 代码的首部插入下面两段代码中的任意一段。</p> +<p> + This algorithm is an exact imitation of the <code>localStorage</code> object, but making use of cookies.</p> +<pre class="brush: js">if (!window.localStorage) { + Object.defineProperty(window, "localStorage", new (function () { + var aKeys = [], oStorage = {}; + Object.defineProperty(oStorage, "getItem", { + value: function (sKey) { return sKey ? this[sKey] : null; }, + writable: false, + configurable: false, + enumerable: false + }); + Object.defineProperty(oStorage, "key", { + value: function (nKeyId) { return aKeys[nKeyId]; }, + writable: false, + configurable: false, + enumerable: false + }); + Object.defineProperty(oStorage, "setItem", { + value: function (sKey, sValue) { + if(!sKey) { return; } + document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/"; + }, + writable: false, + configurable: false, + enumerable: false + }); + Object.defineProperty(oStorage, "length", { + get: function () { return aKeys.length; }, + configurable: false, + enumerable: false + }); + Object.defineProperty(oStorage, "removeItem", { + value: function (sKey) { + if(!sKey) { return; } + var sExpDate = new Date(); + sExpDate.setDate(sExpDate.getDate() - 1); + document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/"; + }, + writable: false, + configurable: false, + enumerable: false + }); + this.get = function () { + var iThisIndx; + for (var sKey in oStorage) { + iThisIndx = aKeys.indexOf(sKey); + if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); } + else { aKeys.splice(iThisIndx, 1); } + delete oStorage[sKey]; + } + for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); } + for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/\s*;\s*/); iCouplId < aCouples.length; iCouplId++) { + iCouple = aCouples[iCouplId].split(/\s*=\s*/); + if (iCouple.length > 1) { + oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]); + aKeys.push(iKey); + } + } + return oStorage; + }; + this.configurable = false; + this.enumerable = true; + })()); +} +</pre> +<div class="note"> + <strong>Note:</strong> The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions <code>localStorage.setItem()</code> and <code>localStorage.removeItem()</code> to add, change or remove a key. The use of methods <code>localStorage.yourKey = yourValue;</code> and <code>delete localStorage.yourKey;</code> to set or delete a key <strong>is not a secure way with this code</strong>. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.</div> +<p> + Here is another, less exact, imitation of the <code>localStorage</code> object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8. It also makes use of cookies.</p> +<pre class="brush: js">if (!window.localStorage) { + window.localStorage = { + getItem: function (sKey) { + if (!sKey || !this.hasOwnProperty(sKey)) { return null; } + return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); + }, + key: function (nKeyId) { return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); }, + setItem: function (sKey, sValue) { + if(!sKey) { return; } + document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/"; + this.length = document.cookie.match(/\=/g).length; + }, + length: 0, + removeItem: function (sKey) { + if (!sKey || !this.hasOwnProperty(sKey)) { return; } + var sExpDate = new Date(); + sExpDate.setDate(sExpDate.getDate() - 1); + document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/"; + this.length--; + }, + hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); } + }; + window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; +} +</pre> +<div class="note"> + <strong>Note:</strong> The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions <code>localStorage.getItem()</code>, <code>localStorage.setItem()</code> and <code>localStorage.removeItem()</code> to get, add, change or remove a key. The use of method <code>localStorage.yourKey</code> in order to get, set or delete a key <strong>is not permitted with this code</strong>. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.</div> +<h5 id="与_globalStorage_的关系的兼容性"> + 与 globalStorage 的关系的兼容性</h5> +<p class="note"> + <code>localStorage</code> is also the same as <code>globalStorage[location.hostname]</code>, with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and <code>localStorage</code> being an instance of <code>Storage</code> as opposed to <code>globalStorage[location.hostname]</code> being an instance of <code>StorageObsolete</code> which is covered below. 例如,在 <a class="external" href="http://example.com" rel="freelink">http://example.com</a> 中不能访问 <a class="link-https" href="https://example.com" rel="freelink">https://example.com</a> 中的 <code>localStorage</code> 对象,但是它们都可以访问同一个 <code>globalStorage。</code> <code>localStorage</code> 是个标准接口,但 <code>globalStorage</code> 是非标准的。所以你的代码最好不要依赖这些关系。</p> +<p> + Please note that setting a property on <code>globalStorage[location.hostname]</code> does <strong>not</strong> set it on <code>localStorage</code> and extending <code>Storage.prototype</code> does not affect <code>globalStorage</code> items, only extending <code>StorageObsolete.prototype</code> does.</p> +<h4 id="globalStorage_2"> + <code>globalStorage</code></h4> +<p> + {{ Non-standard_header() }}{{ obsolete_header("13.0") }}<code>globalStorage </code>is obsolete since Gecko 1.9.1 (Firefox 3.5) and unsupported since Gecko 13 (Firefox 13). Just use<code> {{ Anch("localStorage") }} </code>instead. This proposed addition to HTML 5 has been removed from the HTML 5 specification in favor of <code>localStorage</code>, which is implemented in Firefox 3.5. This is a global object (<code>globalStorage</code>) that maintains multiple private storage areas that can be used to hold data over a long period of time (e.g. over multiple pages and browser sessions).</p> +<div class="warning"> + Note: <code>globalStorage</code> is not a <code>Storage</code> instance, but a <code>StorageList</code> instance containing <code>StorageObsolete</code> instances.</div> +<pre class="eval deki-transform">// Save data that only scripts on the mozilla.org domain can access +globalStorage['mozilla.org'].setItem("snippet", "<b>Hello</b>, how are you?"); +</pre> +<p> + Specifically, the <code>globalStorage</code> object provides access to a number of different storage objects into which data can be stored. For example, if we were to build a web page that used <code>globalStorage</code> on this domain (developer.mozilla.org) we'd have the following storage object available to us:</p> +<ul> + <li> + <code>globalStorage{{ mediawiki.external('\'developer.mozilla.org\'') }}</code> - All web pages within the developer.mozilla.org sub-domain can both read and write data to this storage object.</li> +</ul> +<p> + <strong>例子:</strong></p> +<p> + All of these examples require that you have a script inserted (with each of the following code) in every page that you want to see the result on.</p> +<p> + Remember a user's username for the particular sub-domain that is being visited:</p> +<pre class="eval deki-transform"> globalStorage['developer.mozilla.org'].setItem("username", "John"); +</pre> +<p> + Keep track of the number of times that a user visits all pages of your domain:</p> +<pre class="eval deki-transform"> // parseInt must be used since all data is stored as a string + globalStorage['mozilla.org'].setItem("visits", parseInt(globalStorage['mozilla.org'].getItem("visits") || 0 ) + 1); +</pre> +<h3 id="存储位置以及清除数据"> + 存储位置以及清除数据</h3> +<p> + In Firefox the DOM storage data is stored in the <a class="external" href="http://kb.mozillazine.org/Webappsstore.sqlite" title="http://kb.mozillazine.org/Webappsstore.sqlite">webappsstore.sqlite file</a> in the profile folder (there's also chromeappsstore.sqlite file used to store browser's own data, <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=592990" title="https://bugzilla.mozilla.org/show_bug.cgi?id=592990">notably for the start page - about:home</a>, but potentially for other internal pages with "about:" URLs).</p> +<ul> + <li> + DOM Storage can be cleared via "Tools -> Clear Recent History -> Cookies" when Time range is "Everything" (via nsICookieManager::removeAll) + <ul> + <li> + But not when another time range is specified: (<a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=527667" title="https://bugzilla.mozilla.org/show_bug.cgi?id=527667">bug 527667</a>)</li> + <li> + Does not show up in Tools -> Options -> Privacy -> Remove individual cookies (<a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=506692" title="https://bugzilla.mozilla.org/show_bug.cgi?id=506692">bug 506692</a>)</li> + </ul> + </li> + <li> + DOM Storage is <strong>not</strong> cleared via Tools -> Options -> Advanced -> Network -> Offline data -> Clear Now.</li> + <li> + Doesn't show up in the "Tools -> Options -> Advanced -> Network -> Offline data" list, unless the site also uses the offline cache. If the site does appear in that list, its DOM storage data is removed along with the <a href="/zh-cn/HTML/Using_the_application_cache" title="zh-cn/Offline resources in Firefox">offline cache</a> when clicking the Remove button.</li> +</ul> +<p> + See also <a href="/zh-cn/HTML/Using_the_application_cache#Storage_location_and_clearing_the_offline_cache" title="zh-cn/Offline resources in Firefox#Storage location and clearing the offline cache">clearing offline resources cache</a>.</p> +<h3 id="更多信息"> + 更多信息</h3> +<ul> + <li> + <a class="external" href="http://www.w3.org/TR/webstorage/" title="http://www.w3.org/TR/webstorage/">Web Storage</a> (W3C Web Apps Working Group)</li> + <li> + <a class="external" href="http://kb.mozillazine.org/Dom.storage.enabled">Enable/Disable DOM Storage in Firefox or SeaMonkey</a></li> +</ul> +<h3 id="例子"> + 例子</h3> +<ul> + <li> + <a class="external" href="http://www.diveintojavascript.com/tutorials/web-storage-tutorial-creating-an-address-book-application" title="JavaScript Web Storage Tutorial: Creating an Address Book Application">JavaScript Web Storage Tutorial: Creating an Address Book Application</a> - hands-on tutorial describing how to use the Web Storage API by creating a simple address book application</li> + <li> + <a class="external" href="http://hacks.mozilla.org/2010/01/offline-web-applications/" title="http://hacks.mozilla.org/2010/01/offline-web-applications/">offline web applications</a> at hacks.mozilla.org - showcases an offline app demo and explains how it works.</li> + <li> + <a class="external" href="http://noteboard.eligrey.com/" title="http://noteboard.eligrey.com/">Noteboard</a> - Note writing application that stores all data locally.</li> + <li> + <a class="external" href="http://github.com/eligrey/jData-host" title="http://github.com/eligrey/jData-host">jData</a> - A shared localStorage object interface that can be accessed by any website on the internet and works on Firefox 3+, Webkit 3.1.2+ nightlies, and IE8. Think of it as pseudo-globalStorage[""] but write access needs user confirmation.</li> + <li> + <a class="external" href="http://codebase.es/test/webstorage.html" title="http://codebase.es/test/webstorage.html">HTML 5 localStorage example</a>. Very simple and easy to understand example of localStorage. Saves and retrieves texts and shows a list of saved items. Tested in Firefox 3 or higher.</li> + <li> + <a class="external" href="http://upload.jonathanwilsson.com/html5/sessionstorage.php" title="http://upload.jonathanwilsson.com/html5/sessionstorage.php">HTML5 Session Storage</a>. A very simple example of session storage. Also includes a example on local storage. Tested in Firefox 3.6 or higher.</li> + <li> + <a class="external" href="http://channy.creation.net/work/firefox/domstorage/"><strike>Basic DOMStorage Examples</strike></a><strike> - Broken in Firefox 3 and up due to use of globalStorage on one domain level up from the current domain which is not allowed in Firefox 3.</strike></li> + <li> + <a class="external" href="http://aaronboodman.com/halfnote/"><strike>halfnote</strike></a><strike> - (displaying broken in Firefox 3) Note writing application that uses DOM Storage.</strike></li> +</ul> +<h3 id="浏览器兼容性"> + 浏览器兼容性</h3> +<p> + {{ CompatibilityTable() }}</p> +<div id="compat-desktop"> + <table class="compat-table"> + <tbody> + <tr> + <th> + Feature</th> + <th> + Chrome</th> + <th> + Firefox (Gecko)</th> + <th> + Internet Explorer</th> + <th> + Opera</th> + <th> + Safari (WebKit)</th> + </tr> + <tr> + <td> + localStorage</td> + <td> + 4</td> + <td> + 3.5</td> + <td> + 8</td> + <td> + 10.50</td> + <td> + 4</td> + </tr> + <tr> + <td> + sessionStorage</td> + <td> + 5</td> + <td> + 2</td> + <td> + 8</td> + <td> + 10.50</td> + <td> + 4</td> + </tr> + <tr> + <td> + globalStorage</td> + <td> + {{ CompatNo() }}</td> + <td> + 2-13</td> + <td> + {{ CompatNo() }}</td> + <td> + {{ CompatNo() }}</td> + <td> + {{ CompatNo() }}</td> + </tr> + </tbody> + </table> +</div> +<div id="compat-mobile"> + <table class="compat-table"> + <tbody> + <tr> + <th> + Feature</th> + <th> + Android</th> + <th> + Firefox Mobile (Gecko)</th> + <th> + IE Phone</th> + <th> + Opera Mobile</th> + <th> + Safari Mobile</th> + </tr> + <tr> + <td> + Basic support</td> + <td> + {{ CompatUnknown() }}</td> + <td> + {{ CompatUnknown() }}</td> + <td> + {{ CompatUnknown() }}</td> + <td> + {{ CompatUnknown() }}</td> + <td> + {{ CompatUnknown() }}</td> + </tr> + </tbody> + </table> +</div> +<p> + All browsers have varying capacity levels for both local- and sessionStorage. Here is a <a class="external" href="http://dev-test.nemikor.com/web-storage/support-test/" title="http://dev-test.nemikor.com/web-storage/support-test/">detailed rundown of all the storage capacities for various browsers</a>.</p> +<p> + </p> +<h3 id="相关链接"> + 相关链接</h3> +<ul> + <li> + <a class="external" href="http://en.wikipedia.org/wiki/HTTP_cookie">HTTP cookies</a> (<code><a href="/zh-cn/DOM/document.cookie" title="zh-cn/DOM/document.cookie">document.cookie</a></code>)</li> + <li> + <a class="external" href="http://www.macromedia.com/support/documentation/zh-cn/flashplayer/help/help02.html">Flash Local Storage</a></li> + <li> + <a class="external" href="http://msdn2.microsoft.com/en-us/library/ms531424.aspx">Internet Explorer userData behavior</a></li> + <li> + <a href="/zh-cn/XPCOM_Interface_Reference/nsIDOMStorageEventObsolete" title="zh-cn/XPCOM Interface Reference/nsIDOMStorageEventObsolete">nsIDOMStorageEventObsolete</a></li> + <li> + <a href="/zh-cn/DOM/event/StorageEvent" title="zh-cn/DOM/Event/StorageEvent">StorageEvent</a></li> +</ul> +<p> + {{ HTML5ArticleTOC() }}</p> +<p> + {{ languages( { "es": "es/DOM/Almacenamiento", "fr": "fr/DOM/Storage", "ja": "ja/DOM/Storage", "pl": "pl/DOM/Storage", "en": "en/DOM/Storage" } ) }}</p> +<p> + ---------------------------------</p> +<p> + </p> +<h3 id=".E6.91.98.E8.A6.81" name=".E6.91.98.E8.A6.81"> + 摘要</h3> +<p> + DOM Storage,就是在<a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/">Web Applications 1.0</a> specification中介绍的那些<a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#storage">存储相关特性</a>集合的名称。相比较在cookies中存储信息来说,DOM Stroage更大、更安全、更易于使用的。目前支持的浏览器包括Mozilla Firefox 2+, Google Chrome, Apple Safari, Opera和Microsoft IE9+,在移动设备上也包括iPhone & iPad Safari。</p> +<div class="note"> + <strong>Note:</strong> DOM Storage 与 <a href="/cn/Storage" title="cn/Storage">mozStorage</a> (Mozilla对于SQLite的XPCOM接口)和<a href="/cn/Session_store_API" title="cn/Session_store_API">Session store API</a>(扩展使用的一个<a href="/cn/XPCOM" title="cn/XPCOM">XPCOM</a>存储).不同</div> +<h3 id=".E6.8F.8F.E8.BF.B0" name=".E6.8F.8F.E8.BF.B0"> + 描述</h3> +<p> + DOM Storage机制是一种通过字符串形式的名/值对来安全地存储和使用的方法。这个附加功能的目标是提供一个更全面的、可以创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间)。</p> +<p> + 目前,只有基于Mozilla的浏览器提供了DOM Storage的实现。不过,Internet Explorer也有一个类似的特性,叫做"<a class="external" href="http://msdn.microsoft.com/workshop/author/behaviors/reference/behaviors/userdata.asp">userData behavior</a>",他允许你在多重浏览器会话中永久地保存数据。</p> +<p> + DOM Storage 是很有用的,因为在任何一段时期都没有一个很好的、只通过浏览器来永久存储合理大小的数据的方法。<a class="external" href="http://en.wikipedia.org/wiki/HTTP_cookie">浏览器cookies</a> 限制了存储容量,而且并没有为组织永久性的数据提供支持,并且其他的方法还需要外部插件来实现(例如<a class="external" href="http://www.macromedia.com/support/documentation/zh-cn/flashplayer/help/help02.html">Flash Local Storage</a>)。</p> +<p> + 第一个使用了新的DOM Storage功能(除了Internet Explorer 的 userData Behavior之外)的公共应用程序是由 <a class="external" href="http://aaronboodman.com/">Aaron Boodman</a> 写的 <a class="external" href="http://aaronboodman.com/halfnote/">halfnote</a>(一个便签应用程序) 。在他的程序中,Aaron同时把便签内容保存到服务器上(当Internet连接可用时)和一个本地数据存储中。这就允许用户即便是在不定式发生internet连接中断时,也可以安全的写一些有备份的便签。</p> +<p> + 不过,在halfnote中表现出来的概念和实现,都还是相对简单的。它的诞生揭示了一种新的、可以在线或离线使用的网络应用程序。</p> +<h3 id=".E5.8F.82.E8.80.83" name=".E5.8F.82.E8.80.83"> + 参考</h3> +<p> + 下面的内容都是作为每个<a href="/cn/DOM/window" title="cn/DOM/window"><code>window</code> 对象</a>的属性存在的全局对象。这也就是说,可以通过<code>sessionStorage</code> 或者 <code>window.sessionStorage</code> 来访问它们。(这很重要,因为随后你可以使用iframe来存储、访问、添加那些并不是立刻就包含在你页面中的数据。)</p> +<h4 id="sessionStorage" name="sessionStorage"> + <code>sessionStorage</code></h4> +<p> + 这是一个全局对象(<code>sessionStorage</code>),它含有一个在页面会话有效期内可用的存储区域。只要页面没有关闭,一个页面会话就始终保持着,并且当页面被重新载入或恢复时“复活”。打开一个新的标签页或新窗口都会初始化新的会话。</p> +<pre class="eval">// 将数据存入当前会话的一个存储中 +sessionStorage.username = "John"; + +// 访问某些已存储的数据 +alert( "username = " + sessionStorage.username ); +</pre> +<p> + <code>sessionStorage</code> 对象是最有用的,它持有那些应该保存的临时数据,而且一旦浏览器突然被刷新时,要恢复的那些数据,</p> +<div class="bug"> + <strong>Note:</strong> <code>sessionStorage</code> 还应该有在浏览器崩溃后存储和恢复数据的功能,不过由于{{ Bug(339445) }}的原因,这个功能到现在还没有在Firefox中实现。这个功能实现之后,<code>sessionStorage</code>的防御功能就十分有用了。</div> +<p> + <strong>举例:</strong></p> +<p> + 自动保存文本字段的内容,如果浏览器突然被刷新,就恢复字段内容,这样就不会丢失任何输入了。</p> +<pre class="eval"> // 获得我们要跟踪的那个文本字段 + var field = document.getElementById("field"); + + // 看看我们是否有一个autosave的值 + // (这将只会在页面被突然刷新时发生) + if ( sessionStorage.autosave ) { + // 恢复文本字段中的内容 + field.value = sessionStorage.autosave; + } + + // 每秒钟检查一次文本字段的内容 + setInterval(function(){ + // 并把结果保存到会话存储对象中 + sessionStorage.autosave = field.value; + }, 1000); +</pre> +<p> + <strong>更多信息:</strong></p> +<ul> + <li> + <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#sessionstorage">sessionStorage specification</a></li> +</ul> +<h4 id="globalStorage" name="globalStorage"> + <code>globalStorage</code></h4> +<p> + 这是一个全局对象(<code>globalStorage</code>),它维护着各种公共的或者私有的,可以用来长时期保存数据的存储空间(例如,在多重的页面和浏览器会话之间)。</p> +<pre class="eval">// 可以这样访问那些仅对mozilla.org域上的脚本保存的数据 +globalStorage['mozilla.org'].snippet = "<b>Hello</b>, how are you?"; + +// 可以这样访问为任何网页任何域存储的数据 +globalStorage[<span class="nowiki">''</span>].favBrowser = "Firefox"; +</pre> +<p> + 特别地,<code>globalStorage</code>对象,提供了访问一些不同的可以保存数据的存储对象的方法。例如,如果我们要建立一个可以在域(developer.mozilla.org)下面可以使用<code>globalStorage</code>的网页,我们有下面这些存储对象可以使用:</p> +<ul> + <li> + <code>globalStorage{{ mediawiki.external('\'developer.mozilla.org\'') }}</code> - 在developer.mozilla.org下面所有的子域都可以通过这个存储对象来进行读和写。</li> + <li> + <code>globalStorage{{ mediawiki.external('\'mozilla.org\'') }}</code> - 在mozilla.org域名下面的所有网页都可以通过这个存储对象来进行读和写。</li> + <li> + <code>globalStorage{{ mediawiki.external('\'org\'') }}</code> - 在.org域名下面的所有网页都可以通过这个存储对象来进行读和写。</li> + <li> + <code>globalStorage{{ mediawiki.external('') }}</code> - 在任何域名下的任何网页都可以通过这个存储对象来进行读和写。</li> +</ul> +<div class="bug"> + <strong>注意:</strong> firefox目前还没有实现<code>globalStorage{{ mediawiki.external('tld') }}</code> 和 <code>globalStorage{{ mediawiki.external('') }}</code> (会抛出一个安全错误),这是由于对于这些名字空间可以进行随意读写的话是有安全漏洞的 <a class="external" href="http://ejohn.org/blog/dom-storage-answers/">更多信息</a></div> +<p> + <strong>示例:</strong></p> +<p> + 下面这些示例,需要你在所有想看到效果的页面中都插入脚本(包括如下所有的代码)。</p> +<p> + 记录某个指定子域名下面正在访问的用户的username:</p> +<pre class="eval"> globalStorage['developer.mozilla.org'].username = "John"; +</pre> +<p> + 跟踪一个用户在你的域名下所访问的所有页面的次数:</p> +<pre class="eval"> // 由于所有数据都是被当作一个字符串来保存的,所以这里必须使用parseInt + globalStorage['mozilla.org'].visits = + parseInt( globalStorage['mozilla.org'].visits || 0 ) + 1; +</pre> +<p> + 记录所有你访问的网站:</p> +<pre class="eval"> globalStorage[<span class="nowiki">''</span>].sites += "," + location.hostname; +</pre> +<p> + <strong>更多信息:</strong></p> +<ul> + <li> + <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#globalstorage">globalStorage specification</a></li> +</ul> +<h3 id="More_information" name="More_information"> + More information</h3> +<ul> + <li> + <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/">Web Applications 1.0 Specification</a></li> + <li> + <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#storage">Web Applications 1.0 Storage Specification</a></li> + <li> + <a class="external" href="http://kb.mozillazine.org/Dom.storage.enabled">Enable/Disable DOM Storage in Firefox or SeaMonkey</a></li> +</ul> +<h3 id="Examples" name="Examples"> + Examples</h3> +<ul> + <li> + <a class="external" href="http://channy.creation.net/work/firefox/domstorage/">Basic DOMStorage Examples</a></li> + <li> + <a class="external" href="http://aaronboodman.com/halfnote/">halfnote</a> - Note writing application that uses DOM Storage.</li> +</ul> +<h3 id="Related" name="Related"> + Related</h3> +<ul> + <li> + <a class="external" href="http://en.wikipedia.org/wiki/HTTP_cookie">HTTP cookies</a> (<code><a href="/cn/DOM/document.cookie" title="cn/DOM/document.cookie">document.cookie</a></code>)</li> + <li> + <a class="external" href="http://www.macromedia.com/support/documentation/zh-cn/flashplayer/help/help02.html">Flash Local Storage</a></li> + <li> + <a class="external" href="http://msdn.microsoft.com/workshop/author/behaviors/reference/behaviors/userdata.asp">Internet Explorer userData behavior</a></li> +</ul> diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/index.html new file mode 100644 index 0000000000..da693553b8 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/webrtc_api/index.html @@ -0,0 +1,23 @@ +--- +title: WebRTC API overview +slug: Web/API/WebRTC_API/Overview +translation_of: Web/API/WebRTC_API#WebRTC_concepts_and_usage +translation_of_original: Web/API/WebRTC_API/Overview +--- +<p>{{WebRTCSidebar}}</p> + +<p><span class="seoSummary">WebRTC是由一些关联的API和协议一起协作,支持两个或多个终端之间交换数据和媒体信息的技术。这篇文章提供了这些APIs的介绍和提供的功能。</span></p> + +<h2 id="RTCPeerConnection">RTCPeerConnection</h2> + +<p>在媒体能够交换,或者数据通道建立之前,你需要把两个终端连接起来。这个连接过程的完成就是使用{{domxref("RTCPeerConnection")}} 接口。</p> + +<h2 id="MediaStream">MediaStream</h2> + +<p>{{domxref("MediaStream")}}接口描述了终端之间传输的媒体流。这个流由一个或多个媒体通道信息;通常这是一个音频通道或者视频通道信息。一个媒体流能够传输实时的媒体(例如音频通话或者视频会议等)或者已存的媒体(例如网上电影)。</p> + +<h2 id="RTCDataChannel">RTCDataChannel</h2> + +<p>WebRTC支持在建立连接的两个终端之间相互的传输二进制数据。这个过程通过{{domxref("RTCDataChannel")}}接口。</p> + +<p>这个接口可以作为数据的反向通道,甚至作为主要的数据通道去交换各种数据。例如在游戏应用中,通过这个接口可以实现多玩家支持,相互传送玩家的动作更新之类的数据。</p> diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html new file mode 100644 index 0000000000..5f37d83529 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html @@ -0,0 +1,18 @@ +--- +title: WebRTC 架构概览 +slug: Web/API/WebRTC_API/Architecture +tags: + - WebRTC 架构概览 +translation_of: Web/API/WebRTC_API/Protocols +translation_of_original: Web/API/WebRTC_API/Architecture +--- +<p>{{WebRTCSidebar}}</p> + +<p>用来创建WebRTC连接的API底层使用了一系列的网络协议和连接标准。这篇文章涵盖了这些标准。</p> + +<p>为了让WebRTC正常工作,需要的协议、标准和API比较繁多。因此对于初学者来说可能会比较难以理解。当你一旦上手,你会惊喜地发现原来这一切都是如此的优雅和简单易懂。至于你信不信,反正我是信了。</p> + + + + +<p>重定向 <a class="redirect" href="/zh-Hans/docs/Web/API/WebRTC_API/Protocols">WebRTC 协议介绍</a></p> diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html new file mode 100644 index 0000000000..67464bdbd1 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html @@ -0,0 +1,263 @@ +--- +title: WebRTC basics +slug: Web/API/WebRTC_API/WebRTC_basics +translation_of: Web/API/WebRTC_API/Signaling_and_video_calling +translation_of_original: Web/API/WebRTC_API/WebRTC_basics +--- +<p>{{WebRTCSidebar}}</p> + +<div class="summary"> +<p>当你理解 <a href="/en-US/docs/Web/API/WebRTC_API/Architecture" title="/en-US/docs/Web/Guide/API/WebRTC/WebRTC_architecture">WebRTC 架构</a>之后, 你就可以阅读本篇文章了。本篇文章将带领你贯穿整个跨浏览器 RTC 应用的创建过程。到本章结束的时候,你就拥有了一个可以运行的点对点的数据通道和媒体通道。</p> +</div> + +<div class="note"> +<p><strong>本页的案例过期了! 不要再尝试他们了。</strong></p> +</div> + +<h2 id="注意">注意</h2> + +<p>由于近期 API 做了一些修改,一些比较老的案例需要修复,暂时不可用。</p> + +<ul> + <li><a href="http://louisstow.github.io/WebRTC/media.html">louisstow</a></li> + <li><a href="http://mozilla.github.io/webrtc-landing/">mozilla</a></li> + <li><a href="https://www.webrtc-experiment.com/">webrtc-experiment</a></li> +</ul> + +<p>当前可以正常工作的的案例是:</p> + +<ul> + <li><a href="https://apprtc.appspot.com">apprtc</a> (<a href="https://github.com/webrtc/apprtc">source</a>)</li> +</ul> + +<p>正确的实现方式或许可以从<a href="http://w3c.github.io/webrtc-pc/">标准</a>中推断出来。</p> + +<p>本页包含的其余的过期的信息,在 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1119285">bugzilla</a>。</p> + +<h2 id="Shims">Shims</h2> + +<p>就像你想的那样,这样前卫的 API 肯定需要浏览器前缀才可以,然后再将它转换成通用的变量。</p> + +<pre class="brush: js">var RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection; +var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate; +var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription; +navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;</pre> + +<h2 id="RTCPeerConnection">RTCPeerConnection</h2> + +<p>这是使用 peer 创建连接的起始点。它接收一个配置选项,其中配置了用来创建连接的 ICE 服务器信息。</p> + +<pre class="brush: js">var pc = new RTCPeerConnection(configuration);</pre> + +<h3 id="RTCConfiguration"><strong><code>RTCConfiguration</code></strong></h3> + +<p> {{domxref("RTCConfiguration")}} 对象包含了一些信息,这些信息是关于用来做 ICE 的 TURN 和 / 或 STUN 服务器的。这是用来确保大多数用户可以避免因 NAT 和防火墙导致的无法建立连接。</p> + +<pre class="brush: js">var configuration = { + iceServers: [ + {urls: "stun:23.21.150.121"}, + {urls: "stun:stun.l.google.com:19302"}, + {urls: "turn:numb.viagenie.ca", credential: "webrtcdemo", username: "louis%40mozilla.com"} + ] +}</pre> + +<p>Google 运行了一个我们可以使用的<a href="https://code.google.com/p/natvpn/source/browse/trunk/stun_server_list">公共 STUN 服务器</a>。我也在 http://numb.viagenie.ca/ 创建了一个免费的可以访问 TURN 服务器的账户。可能你也想这么做,你只要替换到你自己的许可证书就可以了。</p> + + + +<h2 id="ICECandidate">ICECandidate</h2> + + + +<p>创建好 PeerConnection 并传入可用的 <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/API/WebRTC/WebRTC_architecture#What_is_STUN.3F">STUN</a> 和 <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/API/WebRTC/WebRTC_architecture#What_is_TURN.3F">TURN</a> 之后,当 ICE 框架找到可以使用 Peer 创建连接的 “候选者”,会立即触发一个事件(onicecandidate)。这些 “候选者” 就是 ICECandidate, 而且他们会在 <a href="/en-US/docs/Web/API/RTCPeerConnection.onicecandidate">PeerConnection#onicecandidate</a> 事件中执行一个回调函数。</p> + +<pre class="brush: js" lang="javascript">pc.onicecandidate = function (e) { + // candidate exists in e.candidate + if (!e.candidate) return; + send("icecandidate", JSON.stringify(e.candidate)); +};</pre> + +<p>回调函数执行之后,我们必须使用信令通道 (signal channel) 将候选发送到其他的点。在 Chrome 中,ICE 框架一般会找到重复的候选者,所以,我一般只发送第一个,然后将处理函数删除。Firfox 中将候选者包含在了 Offer SDP 中。</p> + +<h2 id="Signal_Channel">Signal Channel</h2> + +<p>现在我们有了 ICE 候选,然后需要将它发送到我们的另一端,以让它知道如何跟我们建立连接。然而,现在有一个先有鸡还是先有蛋的问题。我们想要 PeerConnection 发送数据到另一端,但是在那之前我们需要先把元数据发送过去……</p> + +<p>现在就是用到信令通道(Signal Channel)的时候了。它的任何一个数据传输方法都允许两个端点之间交换信息。在本文中,我们将使用 <a href="http://firebase.com">FireBase</a>。因为它设置起来灰常简单,并且不需要任何主机或者服务器端的代码编写。</p> + +<p>现在我们想象只有两个两个方法:send(), 它将使用一个键,然后将数据赋值给它;recv() ,当一个键有值的时候会调用一个处理函数。</p> + +<p>数据库的结构就像下面这样:</p> + +<pre class="brush: js" lang="json">{ + "": { + "candidate:": … + "offer": … + "answer": … + } +}</pre> + +<p>连接会被 roomId 分割,然后会保存四条信息:发起者 (oferer) 的 ICE 候选、应答者 (answerer) 的 ICE 候选、offer SDP 和 answer SDP.</p> + +<h2 id="Offer">Offer</h2> + +<p>Offer SDP 是用来向另一端描述期望格式(视频, 格式, 解编码, 加密, 解析度, 尺寸 等等)的元数据。</p> + +<p>一次信息的交换需要从一端拿到 offer,然后另外一端接受这个 offer 然后返回一个 answer。</p> + +<pre class="brush: js" lang="javascript">pc.createOffer(function (offer) { + pc.setLocalDescription(offer, function() { + send("offer", JSON.stringify(pc.localDescription)); + }, errorHandler); +}, errorHandler, options);</pre> + +<h3 id="errorHandler"><strong><code>errorHandler</code></strong></h3> + +<p>创建 offer 的过程如果出现问题,就会执行这个函数,并且将错误的详细信息作为第一个参数。</p> + +<pre class="brush: js" lang="javascript">var errorHandler = function (err) { + console.error(err); +};</pre> + +<h3 id="options"><strong><code>options</code></strong></h3> + +<p>Offer SDP 的选项.</p> + +<pre class="brush: js" lang="javascript">var options = { + offerToReceiveAudio: true, + offerToReceiveVideo: true +};</pre> + +<p><code>offerToReceiveAudio/Video</code> 告诉另一端,你想接收视频还是音频。对于 DataChannel 来说,这些是不需要的。</p> + +<p>offer 创建好之后,我们必须将本地 SDP 设置进去,然后通过信令通道将它发送到另一端,之久就静静地等待另一端的 Answer SDP 吧.</p> + +<h2 id="Answer">Answer</h2> + +<p>Answer SDP 跟 offer 是差不多的,只不过它是作为相应的。有点像接电话一样。我们只能在接收到 offer 的时候创建一次 Answer.</p> + +<pre class="brush: js" lang="javascript">recv("offer", function (offer) { + offer = new SessionDescription(JSON.parse(offer)) + pc.setRemoteDescription(offer); + + pc.createAnswer(function (answer) { + pc.setLocalDescription(answer, function() { + send("answer", JSON.stringify(pc.localDescription)); + }, errorHandler); + }, errorHandler); +});</pre> + +<h2 id="DataChannel">DataChannel</h2> + +<p>我将首先阐述如何将 PeerConnection 用在 DataChannels API 上,并且如何在 peers 之间传输任意数据。</p> + +<p><em>注意:撰写这篇文章的时候,DataChannels 在 Chrome 和 Firefox 之间是无法互用的。Chrome 支持了一个类似的私有协议,这个协议将在不久被标准协议支持。</em></p> + +<pre class="brush: js" lang="javascript">var channel = pc.createDataChannel(channelName, channelOptions);</pre> + +<p>offer 的创建者和 channel 的创建者应该是同一个 peer。 answer 的创建者将在 PeerConnection 的 ondatachannel 回调中接收到 这个 channel。你必须在创建了这个 offer 之后立即调用 createDataChannel()。</p> + +<h3 id="channelName"><strong><code>channelName</code></strong></h3> + +<p>这个字符串会作为 channel 名字的标签。注意:确保你 Channel 的名字中没有空格,否则在 Chrome 中调用 createAnswer() 将会失败。</p> + +<h3 id="channelOptions"><strong><code>channelOptions</code></strong></h3> + +<pre class="brush: js" lang="javascript">var channelOptions = {};</pre> + +<p>当前 Chrome 还不支持这些选项,所以你可以将这些选项留空。检查 RFC 以获取更多关于这些选项的信息。</p> + +<h3 id="Channel_事件和方法">Channel 事件和方法</h3> + +<h4 id="onopen"><strong><code>onopen</code></strong></h4> + +<p>当连接建立的时候会被执行。</p> + +<h4 id="onerror"><strong><code>onerror</code></strong></h4> + +<p>连接创建出错时执行。第一个参数是一个 error 对象。</p> + +<pre class="brush: js" lang="javascript">channel.onerror = function (err) { + console.error("Channel Error:", err); +};</pre> + +<h4 id="onmessage"><strong><code>onmessage</code></strong></h4> + +<pre class="brush: js" lang="javascript">channel.onmessage = function (e) { + console.log("Got message:", e.data); +}</pre> + +<p>这是连接的核心。当你接收到消息的时候,这个方法会执行。第一个参数是一个包含了数据、接收时间和其它信息的 event 对象。</p> + +<h4 id="onclose"><strong><code>onclose</code></strong></h4> + +<p>当连接关闭的时候执行。</p> + +<h3 id="绑定事件"><strong>绑定事件</strong></h3> + +<p>如果你是这个 channel 的创建者(offerer), 你可以直接在通过 createChannel 创建的 DataChannel 上绑定事件。如果你是 answerer 你必须使用 PeerConnection 的 ondatachannel 回调去访问这个 channel。</p> + +<pre class="brush: js" lang="javascript">pc.ondatachannel = function (e) { + e.channel.onmessage = function () { … }; +};</pre> + +<p>这个 channel 可以在传递到回调函数中的 event 对象中以 e.channel 的方式访问。</p> + +<h4 id="send()"><strong><code>send()</code></strong></h4> + +<pre class="brush: js" lang="javascript">channel.send("Hi Peer!");</pre> + +<p>这个方法允许你直接传递数据到 peer!令人惊奇。你必须传递确保传递的数据是 String, Blob, ArrayBuffer 或者 ArrayBufferView 中的一种类型,所以,确保字符串化对象。</p> + +<h4 id="close()"><strong><code>close()</code></strong></h4> + +<p>在连接应该中止的时候关闭 channel。推荐在页面卸载的时候调用。</p> + +<h2 id="Media">Media</h2> + +<p>现在我们将会涉及到如何传递诸如音视频的媒体的话题。要显示音视频,你必须在文档中加入包含 autoplay 属性的 <video> 标签。</p> + +<h3 id="Get_User_Media">Get User Media</h3> + +<pre class="brush: js"><video id="preview" autoplay></video> + +var video = document.getElementById("preview"); +navigator.getUserMedia(constraints, function (stream) { + video.src = URL.createObjectURL(stream); +}, errorHandler);</pre> + +<p><strong><code>constraints</code></strong></p> + +<p>约定你想从用户获取到的媒体类型。</p> + +<pre class="brush: js" lang="javascript">var constraints = { + video: true, + audio: true +};</pre> + +<p>如果你只想进行音频聊天,移除 video 成员。</p> + +<h4 id="errorHandler_2"><strong><code>errorHandler</code></strong></h4> + +<p>当返回请求的媒体错误时被调用</p> + +<h3 id="Media_Events_and_Methods">Media Events and Methods</h3> + +<h4 id="addStream"><strong><code>addStream</code></strong></h4> + +<p>将从 getUserMedia 返回的流加入 PeerConnection。</p> + +<pre class="brush: js" lang="javascript">pc.addStream(stream);</pre> + +<h4 id="onaddstream"><strong><code>onaddstream</code></strong></h4> + +<pre class="brush: js"><video id="otherPeer" autoplay></video> + +var otherPeer = document.getElementById("otherPeer"); +pc.onaddstream = function (e) { + otherPeer.src = URL.createObjectURL(e.stream); +};</pre> + +<p>当连接建立并且其它的 peer 通过 addStream 将流加入到了连接中时会被调用。你需要另外的 <video> 标签去显示其它 peer 的媒体。</p> + +<p>第一个参数是包含了其它 peer 流媒体的 event 对象。</p> diff --git a/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html b/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html new file mode 100644 index 0000000000..75330b8894 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html @@ -0,0 +1,76 @@ +--- +title: WebRTC +slug: WebRTC +translation_of: Web/API/WebRTC_API +translation_of_original: WebRTC +--- +<p>WebRTC中的RTC是实时通信的简称,这是一种支持在浏览器客户端之间语音/视频交流和数据分享的技术。WebRTC作为一项标准,使得所有浏览器无需安装插件或第三方软件,就可以点对点地分享应用数据和进行电话会议。</p> + +<p>WebRTC组件是通过JavaScript APIs获得的。目前正在开发中的APIs包括:网络流API(能够提供音频和视频),点对点连接API(允许两个或更多用户通过浏览器进行联系)。同样在开发中的还有数据API,能够让浏览器在实时游戏,文字聊天,文件传输和其他应用中与其他类型数据进行交流。</p> + +<table class="topicpage-table"> + <tbody> + <tr> + <td> + <h2 class="Documentation" id="Documentation" name="Documentation">关于Webrtc的文档</h2> + + <dl> + <dt><a href="https://developer.mozilla.org/en-US/docs/WebRTC/Introduction" title="https://developer.mozilla.org/en-US/docs/WebRTC/Introduction">介绍WebRTC</a></dt> + <dd>关于什么是WebRTC以及它是如何工作的一个介绍性指南。</dd> + <dt><a href="/en-US/docs/WebRTC/Using_the_Network_Stream_API" title="/en-US/docs/WebRTC/Using_the_Network_Stream_API">使用网络流 API</a></dt> + <dd>使用网络流API传输音频和视频的指南。</dd> + <dt><a href="/en-US/docs/WebRTC/Using_the_Network_Stream_API" title="/en-US/docs/WebRTC/Using_the_Network_Stream_API">使用网络流API</a></dt> + <dd>指导如何使用网络流API创建音频流和视频流。</dd> + <dt><a href="/en-US/docs/WebRTC/Peer-to-peer_communications_with_WebRTC" title="/en-US/docs/WebRTC/Peer-to-peer_communications_with_WebRTC">运用WebRTC进行点对点通信</a></dt> + <dd>如何使用 WebRTC 的API进行对等通信。</dd> + <dt>使用WebRTC进行点对点通信</dt> + <dd>如何使用WebRTC APTs进行点对点通信交流的指导。</dd> + <dt><a href="/en-US/docs/WebRTC/taking_webcam_photos" title="taking webcam photos">从网络相机获取图像</a></dt> + <dd>介绍 WebRTC 是什么并如何工作。</dd> + <dt>从网络摄像头获得图像</dt> + <dd>介绍如何利用 WebRTC 通过网络摄像头获得图像。</dd> + <dt><a href="/en-US/docs/WebRTC/MediaStream_API" title="/en-US/docs/WebRTC/MediaStream_API">MediaStream API</a></dt> + <dd>这个API支持媒体流对象的生成和操作。</dd> + <dt>多媒体API</dt> + <dd>这个API支持通用多媒体对象。</dd> + <dt><a href="/en-US/docs/WebRTC/navigator.getUserMedia" title="/en-US/docs/">getUserMedia()</a></dt> + <dd>这个函数能获取系统媒体设备。</dd> + </dl> + + <p><span class="alllinks"><a href="/en-US/docs/tag/WebRTC" title="/en-US/docs/tag/B2G">查看全部...</a></span></p> + </td> + <td> + <h2 class="Community" id="Community" name="Community">从社区获取帮助</h2> + + <p> </p> + + <p>在开发利用WebRTC技术的网站和Web应用程序时,与其他人进行对话可能会很有用。</p> + + <ul> + <li>咨询媒体主题论坛: {{ DiscussionList("dev-media", "mozilla.dev.media") }}</li> + </ul> + + <ul> + <li>Mozilla's Media IRC 通道提出你的问题: <a class="link-irc" href="irc://irc.mozilla.org/media" title="irc://irc.mozilla.org/b2g">#media</a></li> + </ul> + + <p><span class="alllinks"><a class="external" href="http://www.catb.org/~esr/faqs/smart-questions.html" title="http://www.catb.org/~esr/faqs/smart-questions.html">不要忘记网络礼节...</a></span></p> + + + <h2 class="Related_Topics" id="Related_Topics" name="Related_Topics">相关话题</h2> + + <ul> + <li><a href="/en-US/docs/Using_HTML5_audio_and_video" title="/en-US/docs/Using_HTML5_audio_and_video">使用 HTML5 音频 和 </a>视频</li> + </ul> + + <h2 class="Tools" id="相关资源">相关资源</h2> + + <ul> + <li>{{spec("http://www.w3.org/TR/webrtc/", "WebRTC specification", "wd")}}</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<p> </p> diff --git a/files/zh-cn/conflicting/web/api/window/localstorage/index.html b/files/zh-cn/conflicting/web/api/window/localstorage/index.html new file mode 100644 index 0000000000..46384c660e --- /dev/null +++ b/files/zh-cn/conflicting/web/api/window/localstorage/index.html @@ -0,0 +1,136 @@ +--- +title: LocalStorage +slug: Web/API/Storage/LocalStorage +tags: + - 存储API + - 离线 +translation_of: Web/API/Window/localStorage +translation_of_original: Web/API/Web_Storage_API/Local_storage +--- +<p><code>localStorage</code> 与<code> <a href="/en-US/docs/Web/API/sessionStorage">sessionStorage</a></code> 一样,都遵循同源策略,但是它是持续存在的。<code>localStorage</code> 首次出现于 Firefox 3.5。</p> + +<div class="note"><strong>Note:</strong> 当浏览器进入隐私浏览模式,会创建一个新的、临时的数据库来存储local storage的数据;当关闭隐私浏览模式时,该数据库将被清空并丢弃。</div> + +<pre class="brush:js" style="font-size: 14px;">// Save data to the current local store +localStorage.setItem("username", "John"); + +// Access some stored data +alert( "username = " + localStorage.getItem("username"));</pre> + +<p class="note">本地存储(<code>localStorage</code>)的持续存在对许多事情都有帮助,包括这个示例<a href="http://codepen.io/awesom3/pen/Hlfma">this tutorial on Codepen</a>所演示的记录页面查看次数。</p> + +<h4 id="兼容性" style="line-height: 18px; font-size: 1.28571428571429rem;">兼容性</h4> + +<p><code>Storage</code> 对象最近才加入标准,因此可能并不被所有浏览器支持。你可以通过在你的scripts代码前加入以下两段代码中某一段来规避在不能原生支持的执行环境使用<code>localStorage</code>对象的问题。</p> + +<p>该算法借助于cookies,对localStorage对象进行了严谨的实现。</p> + +<pre class="brush: js" style="font-size: 14px;">if (!window.localStorage) { + Object.defineProperty(window, "localStorage", new (function () { + var aKeys = [], oStorage = {}; + Object.defineProperty(oStorage, "getItem", { + value: function (sKey) { return sKey ? this[sKey] : null; }, + writable: false, + configurable: false, + enumerable: false + }); + Object.defineProperty(oStorage, "key", { + value: function (nKeyId) { return aKeys[nKeyId]; }, + writable: false, + configurable: false, + enumerable: false + }); + Object.defineProperty(oStorage, "setItem", { + value: function (sKey, sValue) { + if(!sKey) { return; } + document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; + }, + writable: false, + configurable: false, + enumerable: false + }); + Object.defineProperty(oStorage, "length", { + get: function () { return aKeys.length; }, + configurable: false, + enumerable: false + }); + Object.defineProperty(oStorage, "removeItem", { + value: function (sKey) { + if(!sKey) { return; } + document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; + }, + writable: false, + configurable: false, + enumerable: false + }); + this.get = function () { + var iThisIndx; + for (var sKey in oStorage) { + iThisIndx = aKeys.indexOf(sKey); + if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); } + else { aKeys.splice(iThisIndx, 1); } + delete oStorage[sKey]; + } + for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); } + for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) { + aCouple = aCouples[nIdx].split(/\s*=\s*/); + if (aCouple.length > 1) { + oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]); + aKeys.push(iKey); + } + } + return oStorage; + }; + this.configurable = false; + this.enumerable = true; + })()); +} +</pre> + +<div class="note"><strong>注意:</strong>数据的最大大小是通过cookies来严格限制的。可以使用这样的算法实现,使用<code>localStorage.setItem()</code>和<code>localStorage.removeItem()</code>这两个函数进行添加、改变或删除一个键。使用方法为<code>localStorage.yourKey = yourValue;和delete localStorage.yourKey;</code>进行设置和删除一个键<strong>并不是安全的做法</strong>。您也可以改变它的名字和使用它仅仅去管理文档的cookies而不管<code>localStorage </code>这个对象。</div> + +<div class="note"><strong>注意:</strong>通过将字符串<code style="background: rgb(204, 204, 204);">"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"</code> 改成<code style="background: rgb(204, 204, 204);">"; path=/"</code>(并且改变对象的名字),可以使得这个 <code>localStorage</code>的实现变为<code>sessionStorage</code>的实现。然而,这种实现方式会使储存键值可以跨标签和窗口访问(而且只会在浏览器窗口被关闭时销毁),完全兼容的<code>sessionStorage</code>实现会将储存键值访问权限限定在当前浏览上下文。</div> + +<p>下面是另一个,并不那么严谨的<code>localStorage</code>对象的实现。相比上一个方法,它更简单且能与旧的浏览器良好兼容,如Internet Explorer < 8 (甚至能在<strong> Internet Explorer 6 上正常工作</strong>)。它同样是使用cookies来实现的。</p> + +<pre class="brush:js" style="font-size: 14px;">if (!window.localStorage) { + window.localStorage = { + getItem: function (sKey) { + if (!sKey || !this.hasOwnProperty(sKey)) { return null; } + return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); + }, + key: function (nKeyId) { + return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); + }, + setItem: function (sKey, sValue) { + if(!sKey) { return; } + document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; + this.length = document.cookie.match(/\=/g).length; + }, + length: 0, + removeItem: function (sKey) { + if (!sKey || !this.hasOwnProperty(sKey)) { return; } + document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; + this.length--; + }, + hasOwnProperty: function (sKey) { + return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); + } + }; + window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; +} +</pre> + +<div class="note"><strong>注意:</strong>数据量的最大值是通过cookies来严格限制的。可以使用<code>localStorage.getItem()</code>, <code>localStorage.setItem()</code>和<code>localStorage.removeItem()</code>等方法获取、设置或删除一个键。使用方法<code>localStorage.yourKey = yourValue;</code>获取、添加、改变或者删除一个键<strong>并不是安全的做法</strong>。您也可以改变它的名字和使用它仅仅去管理文档的cookies而不管<code>localStorage </code>这个对象。</div> + +<div class="note"><strong>注意:</strong>通过将字符串<code style="background: rgb(204, 204, 204);">"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"</code> 改成<code style="background: rgb(204, 204, 204);">"; path=/"</code>(并且改变对象的名字),可以使得这个 <code>localStorage</code>的实现变为<code>sessionStorage</code>的实现。然而,这种实现方式会使储存键值可以跨标签和窗口访问(而且只会在浏览器窗口被关闭时销毁),完全兼容的sessionStorage实现会将储存键值限定在当前浏览环境上下文。</div> + +<h4 id="与globalStorage的兼容性及关系" style="line-height: 18px; font-size: 1.28571428571429rem;">与globalStorage的兼容性及关系</h4> + +<p class="note"><code>localStorage</code> 和 <code>globalStorage[location.hostname]</code> 是一样的, 除了作用域是在 HTML5 origin (结构 + 主机名 + 非标准的端口), 并且 <code>localStorage</code> 是一个 <code>Storage</code> 实例 ,而<code>globalStorage[location.hostname]</code> 是一个 <code>StorageObsolete</code> 实例,下面将要讨论这个。 例如, <a class="external" href="http://example.com" rel="freelink">http://example.com</a> 无法访问与 <a class="link-https" href="https://example.com" rel="freelink">https://example.com</a> 相同的 <code>localStorage</code> 对象 ,但是它们可以访问同一个 <code>globalStorage</code>. <code>localStorage</code> 是标准的接口,<code>globalStorage</code> 不是, 所以不要依赖于 <code>globalStorage</code> 。 </p> + +<p>请注意,给globalStorage[location.hostname]设置一个属性并不会影响到localStorage。拓展<code>Storage.prototype</code>也不会影响<code>globalStorage</code>对象,只有拓展<code>StorageObsolete.prototype</code>才会影响。</p> + +<h4 id="存储格式">存储格式</h4> + +<p><code>Storage</code>的键和值都是以每个字符占2个字节的UTF-16字符串(<a href="/zh-CN/docs/Web/API/DOMString">DOMString</a>)格式存储的。</p> diff --git a/files/zh-cn/conflicting/web/api/window/moveto/index.html b/files/zh-cn/conflicting/web/api/window/moveto/index.html new file mode 100644 index 0000000000..140827ddb9 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/window/moveto/index.html @@ -0,0 +1,17 @@ +--- +title: Window.restore() +slug: Web/API/Window/restore +translation_of: Web/API/Window/moveTo +translation_of_original: Web/API/Window/restore +--- +<p>{{APIRef}}</p> + +<p>这个方法现在已经失效,不过可以使用下面的方法代替:</p> + +<p>{{domxref("window.moveTo")}}({{domxref("window.screenX")}}, {{domxref("window.screenY")}});</p> + +<h2 id="Browser_Compatibility">Browser Compatibility</h2> + + + +<p>{{Compat("api.Window.restore")}}</p> |