renovations, new pics from @bezart
|
@ -11,13 +11,13 @@
|
||||||
<path d="M25,123 L25,95 L10,123" id="Shape" fill="#E8C48F" sketch:type="MSShapeGroup"></path>
|
<path d="M25,123 L25,95 L10,123" id="Shape" fill="#E8C48F" sketch:type="MSShapeGroup"></path>
|
||||||
<g id="Rectangle-5-+-"World!"" transform="translate(0.000000, 57.000000)">
|
<g id="Rectangle-5-+-"World!"" transform="translate(0.000000, 57.000000)">
|
||||||
<path d="M18.9106925,0.395208397 L73.4146415,58.8435379 L55.0893075,75.9321883 L0.585358502,17.4838588 L18.9106925,0.395208397 L18.9106925,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
<path d="M18.9106925,0.395208397 L73.4146415,58.8435379 L55.0893075,75.9321883 L0.585358502,17.4838588 L18.9106925,0.395208397 L18.9106925,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
||||||
<text id=""World!"" sketch:type="MSTextLayer" transform="translate(39.885486, 40.782373) rotate(47.000000) translate(-39.885486, -40.782373) " font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id=""World!"" sketch:type="MSTextLayer" transform="translate(39.885486, 39.782373) rotate(47.000000) translate(-39.885486, -39.782373) " font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="10.392998" y="46.2823729">"World!"</tspan>
|
<tspan x="10.392998" y="46.2823729">"World!"</tspan>
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="Rectangle-5-+-"World!"-2" transform="translate(139.643781, 49.254803) rotate(293.000000) translate(-139.643781, -49.254803) translate(102.643781, 11.254803)">
|
<g id="Rectangle-5-+-"World!"-2" transform="translate(139.643781, 49.254803) rotate(293.000000) translate(-139.643781, -49.254803) translate(102.643781, 11.254803)">
|
||||||
<path d="M18.9106925,0.395208397 L73.4146415,58.8435379 L55.0893075,75.9321883 L0.585358502,17.4838588 L18.9106925,0.395208397 L18.9106925,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
<path d="M18.9106925,0.395208397 L73.4146415,58.8435379 L55.0893075,75.9321883 L0.585358502,17.4838588 L18.9106925,0.395208397 L18.9106925,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
||||||
<text id=""Hello!"" sketch:type="MSTextLayer" transform="translate(39.885486, 40.782373) rotate(47.000000) translate(-39.885486, -40.782373) " font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id=""Hello!"" sketch:type="MSTextLayer" transform="translate(39.885486, 39.782373) rotate(47.000000) translate(-39.885486, -39.782373) " font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="10.392998" y="46.2823729">"Hello!"</tspan>
|
<tspan x="10.392998" y="46.2823729">"Hello!"</tspan>
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
|
@ -12,7 +12,7 @@
|
||||||
<path d="M17,66 L17,38 L2,66" id="Shape" fill="#E8C48F" sketch:type="MSShapeGroup"></path>
|
<path d="M17,66 L17,38 L2,66" id="Shape" fill="#E8C48F" sketch:type="MSShapeGroup"></path>
|
||||||
<g id="Rectangle-5-+-"World!"" transform="translate(15.000000, 0.000000)">
|
<g id="Rectangle-5-+-"World!"" transform="translate(15.000000, 0.000000)">
|
||||||
<path d="M18.9106925,0.395208397 L73.4146415,58.8435379 L55.0893075,75.9321883 L0.585358502,17.4838588 L18.9106925,0.395208397 L18.9106925,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
<path d="M18.9106925,0.395208397 L73.4146415,58.8435379 L55.0893075,75.9321883 L0.585358502,17.4838588 L18.9106925,0.395208397 L18.9106925,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
||||||
<text id=""Hello!"" sketch:type="MSTextLayer" transform="translate(39.885486, 40.782373) rotate(47.000000) translate(-39.885486, -40.782373) " font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id=""Hello!"" sketch:type="MSTextLayer" transform="translate(39.885486, 39.782373) rotate(47.000000) translate(-39.885486, -39.782373) " font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="10.392998" y="46.2823729">"Hello!"</tspan>
|
<tspan x="10.392998" y="46.2823729">"Hello!"</tspan>
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 82 KiB |
|
@ -12,7 +12,7 @@
|
||||||
<path d="M17,66 L17,38 L2,66" id="Shape" fill="#E8C48F" sketch:type="MSShapeGroup"></path>
|
<path d="M17,66 L17,38 L2,66" id="Shape" fill="#E8C48F" sketch:type="MSShapeGroup"></path>
|
||||||
<g id="Rectangle-5-+-"World!"" transform="translate(15.000000, 0.000000)">
|
<g id="Rectangle-5-+-"World!"" transform="translate(15.000000, 0.000000)">
|
||||||
<path d="M18.9106925,0.395208397 L73.4146415,58.8435379 L55.0893075,75.9321883 L0.585358502,17.4838588 L18.9106925,0.395208397 L18.9106925,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
<path d="M18.9106925,0.395208397 L73.4146415,58.8435379 L55.0893075,75.9321883 L0.585358502,17.4838588 L18.9106925,0.395208397 L18.9106925,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
||||||
<text id=""Привет!"" sketch:type="MSTextLayer" transform="translate(40.359759, 40.417209) rotate(47.000000) translate(-40.359759, -40.417209) " font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id=""Привет!"" sketch:type="MSTextLayer" transform="translate(40.359759, 39.417209) rotate(47.000000) translate(-40.359759, -39.417209) " font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="3.68215005" y="45.9172093">"Привет!"</tspan>
|
<tspan x="3.68215005" y="45.9172093">"Привет!"</tspan>
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<path d="M18,66 L18,38 L2,66" id="Shape" fill="#E8C48F" sketch:type="MSShapeGroup"></path>
|
<path d="M18,66 L18,38 L2,66" id="Shape" fill="#E8C48F" sketch:type="MSShapeGroup"></path>
|
||||||
<g id="Rectangle-5-+-"World!"" transform="translate(15.000000, 0.000000)">
|
<g id="Rectangle-5-+-"World!"" transform="translate(15.000000, 0.000000)">
|
||||||
<path d="M19.1662424,0.395208397 L74.4067312,58.8435379 L55.8337576,75.9321883 L0.593268752,17.4838588 L19.1662424,0.395208397 L19.1662424,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
<path d="M19.1662424,0.395208397 L74.4067312,58.8435379 L55.8337576,75.9321883 L0.593268752,17.4838588 L19.1662424,0.395208397 L19.1662424,0.395208397 Z" id="Rectangle-5" stroke="#8A704D" stroke-width="2" fill="#FFF9EB" sketch:type="MSShapeGroup"></path>
|
||||||
<text id=""Привет!"" sketch:type="MSTextLayer" transform="translate(39.891647, 38.685856) rotate(47.000000) translate(-39.891647, -38.685856) " font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id=""Привет!"" sketch:type="MSTextLayer" transform="translate(39.891647, 37.685856) rotate(47.000000) translate(-39.891647, -37.685856) " font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="3.40960987" y="44.1858556">"Привет!"</tspan>
|
<tspan x="3.40960987" y="44.1858556">"Привет!"</tspan>
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
@ -8,18 +8,18 @@
|
||||||
<g id="array-speed.svg" sketch:type="MSArtboardGroup">
|
<g id="array-speed.svg" sketch:type="MSArtboardGroup">
|
||||||
<rect id="Rectangle-1" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="108" y="92" width="37" height="64"></rect>
|
<rect id="Rectangle-1" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="108" y="92" width="37" height="64"></rect>
|
||||||
<rect id="Rectangle-2" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="144" y="92" width="37" height="64"></rect>
|
<rect id="Rectangle-2" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="144" y="92" width="37" height="64"></rect>
|
||||||
<text id="0" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id="0" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="122.5" y="128.5">0</tspan>
|
<tspan x="122.5" y="128.5">0</tspan>
|
||||||
</text>
|
</text>
|
||||||
<text id="1" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id="1" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="159.5" y="128.5">1</tspan>
|
<tspan x="159.5" y="128.5">1</tspan>
|
||||||
</text>
|
</text>
|
||||||
<rect id="Rectangle-3" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="180" y="92" width="37" height="64"></rect>
|
<rect id="Rectangle-3" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="180" y="92" width="37" height="64"></rect>
|
||||||
<text id="2" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id="2" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="195.5" y="128.5">2</tspan>
|
<tspan x="195.5" y="128.5">2</tspan>
|
||||||
</text>
|
</text>
|
||||||
<rect id="Rectangle-4" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="216" y="92" width="37" height="64"></rect>
|
<rect id="Rectangle-4" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="216" y="92" width="37" height="64"></rect>
|
||||||
<text id="3" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" fill="#8A704D">
|
<text id="3" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
<tspan x="231.5" y="128.5">3</tspan>
|
<tspan x="231.5" y="128.5">3</tspan>
|
||||||
</text>
|
</text>
|
||||||
<path d="M326.5,117.5 L331,111.30787 L328,111.30787 L328,95.5 L325,95.5 L325,111.30787 L322,111.30787 L326.5,117.5 Z" id="Shape-5" fill="#EE6B47" sketch:type="MSShapeGroup" transform="translate(326.500000, 106.500000) rotate(-90.000000) translate(-326.500000, -106.500000) "></path>
|
<path d="M326.5,117.5 L331,111.30787 L328,111.30787 L328,95.5 L325,95.5 L325,111.30787 L322,111.30787 L326.5,117.5 Z" id="Shape-5" fill="#EE6B47" sketch:type="MSShapeGroup" transform="translate(326.500000, 106.500000) rotate(-90.000000) translate(-326.500000, -106.500000) "></path>
|
||||||
|
|
Before Width: | Height: | Size: 8 KiB After Width: | Height: | Size: 8.1 KiB |
|
@ -6,7 +6,7 @@
|
||||||
<defs></defs>
|
<defs></defs>
|
||||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||||
<g id="document-client-width-height.svg" sketch:type="MSArtboardGroup">
|
<g id="document-client-width-height.svg" sketch:type="MSArtboardGroup">
|
||||||
<g id="noun_69008_cc" sketch:type="MSLayerGroup" transform="translate(236.000000, 8.000000)" fill="#E8C48E">
|
<g id="noun_69008_cc" sketch:type="MSLayerGroup" transform="translate(276.000000, 8.000000)" fill="#E8C48E">
|
||||||
<path d="M179.1875,145 L3.8125,145 C1.708,145 0,143.36875 0,141.375 L0,3.625 C0,1.63125 1.708,0 3.8125,0 L179.1875,0 C181.284375,0 183,1.63125 183,3.625 L183,141.375 C183,143.36875 181.284375,145 179.1875,145 L179.1875,145 Z M7.625,137.75 L175.375,137.75 L175.375,7.25 L7.625,7.25 L7.625,137.75 L7.625,137.75 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
<path d="M179.1875,145 L3.8125,145 C1.708,145 0,143.36875 0,141.375 L0,3.625 C0,1.63125 1.708,0 3.8125,0 L179.1875,0 C181.284375,0 183,1.63125 183,3.625 L183,141.375 C183,143.36875 181.284375,145 179.1875,145 L179.1875,145 Z M7.625,137.75 L175.375,137.75 L175.375,7.25 L7.625,7.25 L7.625,137.75 L7.625,137.75 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||||
<path d="M175.375,36.25 L7.625,36.25 C5.5205,36.25 3.8125,34.61875 3.8125,32.625 C3.8125,30.63125 5.5205,29 7.625,29 L175.375,29 C177.471875,29 179.1875,30.63125 179.1875,32.625 C179.1875,34.61875 177.471875,36.25 175.375,36.25 L175.375,36.25 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
<path d="M175.375,36.25 L7.625,36.25 C5.5205,36.25 3.8125,34.61875 3.8125,32.625 C3.8125,30.63125 5.5205,29 7.625,29 L175.375,29 C177.471875,29 179.1875,30.63125 179.1875,32.625 C179.1875,34.61875 177.471875,36.25 175.375,36.25 L175.375,36.25 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||||
<path d="M61.32025,126.57775 C60.0545,126.57775 58.811625,125.98325 58.08725,124.89575 L34.892,89.84925 C34.060875,88.57325 34.121875,86.97825 35.052125,85.7675 L58.247375,55.86125 C59.497875,54.23 61.876875,53.8965 63.57725,55.1145 C65.27,56.3035 65.636,58.57275 64.377875,60.18225 L42.7305,88.102 L64.538,121.05325 C65.658875,122.7425 65.125125,124.99 63.340875,126.04125 C62.72325,126.411 62.014125,126.57775 61.32025,126.57775 L61.32025,126.57775 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
<path d="M61.32025,126.57775 C60.0545,126.57775 58.811625,125.98325 58.08725,124.89575 L34.892,89.84925 C34.060875,88.57325 34.121875,86.97825 35.052125,85.7675 L58.247375,55.86125 C59.497875,54.23 61.876875,53.8965 63.57725,55.1145 C65.27,56.3035 65.636,58.57275 64.377875,60.18225 L42.7305,88.102 L64.538,121.05325 C65.658875,122.7425 65.125125,124.99 63.340875,126.04125 C62.72325,126.411 62.014125,126.57775 61.32025,126.57775 L61.32025,126.57775 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||||
|
@ -16,14 +16,18 @@
|
||||||
<path d="M38.125,18.125 C38.125,20.1278125 36.4189062,21.75 34.3125,21.75 C32.2060938,21.75 30.5,20.1278125 30.5,18.125 C30.5,16.1221875 32.2060938,14.5 34.3125,14.5 C36.4189062,14.5 38.125,16.1221875 38.125,18.125 L38.125,18.125 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
<path d="M38.125,18.125 C38.125,20.1278125 36.4189062,21.75 34.3125,21.75 C32.2060938,21.75 30.5,20.1278125 30.5,18.125 C30.5,16.1221875 32.2060938,14.5 34.3125,14.5 C36.4189062,14.5 38.125,16.1221875 38.125,18.125 L38.125,18.125 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||||
<path d="M53.375,18.125 C53.375,20.1278125 51.6689062,21.75 49.5625,21.75 C47.4560938,21.75 45.75,20.1278125 45.75,18.125 C45.75,16.1221875 47.4560938,14.5 49.5625,14.5 C51.6689062,14.5 53.375,16.1221875 53.375,18.125 L53.375,18.125 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
<path d="M53.375,18.125 C53.375,20.1278125 51.6689062,21.75 49.5625,21.75 C47.4560938,21.75 45.75,20.1278125 45.75,18.125 C45.75,16.1221875 47.4560938,14.5 49.5625,14.5 C51.6689062,14.5 53.375,16.1221875 53.375,18.125 L53.375,18.125 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||||
</g>
|
</g>
|
||||||
<path d="M274.078672,96.0852289 L254.783869,88.4952289 C254.041565,88.2042289 253.073012,88.0582289 252.099374,88.0582289 C251.128279,88.0582289 250.154641,88.2042289 249.41488,88.4952289 C247.932815,89.0792289 247.932815,90.0242289 249.41488,90.6072289 L263.343236,96.0852289 L218.459304,96.0852289 C218.451678,96.0852289 218.444051,96.0862289 218.433883,96.0862289 L185.561537,96.0862289 L199.489894,90.6082289 C200.971959,90.0242289 200.971959,89.0792289 199.489894,88.4962289 C198.005287,87.9132289 195.60297,87.9132289 194.120905,88.4962289 L171.030695,97.5792289 L174.826102,99.0732289 L194.120905,106.663229 C194.863209,106.954229 195.831762,107.101229 196.8054,107.101229 C197.776495,107.101229 198.750133,106.954229 199.489894,106.663229 C200.971959,106.079229 200.971959,105.134229 199.489894,104.551229 L185.561537,99.0732289 L230.44547,99.0732289 C230.453096,99.0732289 230.460723,99.0722289 230.470891,99.0722289 L263.343236,99.0722289 L249.41488,104.550229 C247.932815,105.134229 247.932815,106.079229 249.41488,106.662229 C250.899486,107.245229 253.301804,107.245229 254.783869,106.662229 L277.874079,97.5792289 L274.078672,96.0852289" id="Fill-25" fill="#EE6B47" sketch:type="MSShapeGroup" transform="translate(224.452387, 97.579729) rotate(-91.000000) translate(-224.452387, -97.579729) "></path>
|
|
||||||
<path d="M408.414472,164.793761 L375.121164,157.203761 C373.840315,156.912761 372.16907,156.766761 370.489052,156.766761 C368.81342,156.766761 367.133402,156.912761 365.856939,157.203761 C363.299627,157.787761 363.299627,158.732761 365.856939,159.315761 L389.890409,164.793761 L312.442893,164.793761 C312.429734,164.793761 312.416574,164.794761 312.399028,164.794761 L255.677584,164.794761 L279.711053,159.316761 C282.268365,158.732761 282.268365,157.787761 279.711053,157.204761 C277.149355,156.621761 273.00414,156.621761 270.446828,157.204761 L230.604521,166.287761 L237.15352,167.781761 L270.446828,175.371761 C271.727678,175.662761 273.398923,175.809761 275.078941,175.809761 C276.754572,175.809761 278.43459,175.662761 279.711053,175.371761 C282.268365,174.787761 282.268365,173.842761 279.711053,173.259761 L255.677584,167.781761 L333.125099,167.781761 C333.138259,167.781761 333.151418,167.780761 333.168964,167.780761 L389.890409,167.780761 L365.856939,173.258761 C363.299627,173.842761 363.299627,174.787761 365.856939,175.370761 C368.418638,175.953761 372.563852,175.953761 375.121164,175.370761 L414.963472,166.287761 L408.414472,164.793761" id="Fill-26" fill="#EE6B47" sketch:type="MSShapeGroup" transform="translate(322.783996, 166.288261) rotate(-179.000000) translate(-322.783996, -166.288261) "></path>
|
|
||||||
<text id="documentElement.clie" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#8A704D">
|
<text id="documentElement.clie" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#8A704D">
|
||||||
<tspan x="4" y="99">documentElement.clientHeight</tspan>
|
<tspan x="19" y="89">documentElement.clientHeight</tspan>
|
||||||
</text>
|
</text>
|
||||||
<text id="document.documentEle" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#8A704D">
|
<text id="document.documentEle" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#8A704D">
|
||||||
<tspan x="253" y="198">document.documentElement.clientWidth</tspan>
|
<tspan x="229" y="197">document.documentElement.clientWidth</tspan>
|
||||||
</text>
|
</text>
|
||||||
|
<path d="M457.012291,168.153273 L277.502296,168.153273" id="Line-3" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" fill="#EE6B47" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path id="Line-3-decoration-1" d="M278.012291,168.153273 C281.792291,169.203273 285.032291,170.103273 288.812291,171.153273 C288.812291,169.053273 288.812291,167.253273 288.812291,165.153273 C285.032291,166.203273 281.792291,167.103273 278.012291,168.153273 C278.012291,168.153273 278.012291,168.153273 278.012291,168.153273 Z" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" fill="#EE6B47"></path>
|
||||||
|
<path id="Line-3-decoration-2" d="M456.212291,168.153273 C452.432291,169.203273 449.192291,170.103273 445.412291,171.153273 C445.412291,169.053273 445.412291,167.253273 445.412291,165.153273 C449.192291,166.203273 452.432291,167.103273 456.212291,168.153273 C456.212291,168.153273 456.212291,168.153273 456.212291,168.153273 Z" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" fill="#EE6B47"></path>
|
||||||
|
<path d="M257.5,151.012291 L257.5,14.5022964" id="Line" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" fill="#EE6B47" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path id="Line-decoration-1" d="M257.5,15.012291 C256.45,18.792291 255.55,22.032291 254.5,25.812291 C256.6,25.812291 258.4,25.812291 260.5,25.812291 C259.45,22.032291 258.55,18.792291 257.5,15.012291 C257.5,15.012291 257.5,15.012291 257.5,15.012291 Z" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" fill="#EE6B47"></path>
|
||||||
|
<path id="Line-decoration-2" d="M257.5,150.212291 C256.45,146.432291 255.55,143.192291 254.5,139.412291 C256.6,139.412291 258.4,139.412291 260.5,139.412291 C259.45,143.192291 258.55,146.432291 257.5,150.212291 C257.5,150.212291 257.5,150.212291 257.5,150.212291 Z" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" fill="#EE6B47"></path>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.1 KiB |
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
Всплытие гарантирует, что клик по внутреннему `<p>` вызовет обработчик `onclick` (если есть) сначала на самом `<p>`, затем на элементе `<div>` далее на элементе `<form>`, и так далее вверх по цепочке родителей до самого `document`.
|
Всплытие гарантирует, что клик по внутреннему `<p>` вызовет обработчик `onclick` (если есть) сначала на самом `<p>`, затем на элементе `<div>` далее на элементе `<form>`, и так далее вверх по цепочке родителей до самого `document`.
|
||||||
|
|
||||||
<img src="event-order-bubbling.png" alt="Порядок всплытия событий">
|
<img src="event-order-bubbling.svg" alt="Порядок всплытия событий">
|
||||||
|
|
||||||
Поэтому если в примере выше кликнуть на `P`, то последовательно выведутся `alert`: `p` -> `div` -> `form`.
|
Поэтому если в примере выше кликнуть на `P`, то последовательно выведутся `alert`: `p` -> `div` -> `form`.
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
|
|
||||||
В [стандарте DOM Events 3](http://www.w3.org/TR/DOM-Level-3-Events/) это продемонстрировано так:
|
В [стандарте DOM Events 3](http://www.w3.org/TR/DOM-Level-3-Events/) это продемонстрировано так:
|
||||||
|
|
||||||
<img src="eventflow.png">
|
<img src="eventflow.svg">
|
||||||
|
|
||||||
То есть, при клике на `TD` событие путешествует по цепочке родителей сначала вниз к элементу ("погружается"), а потом наверх ("всплывает"), по пути задействуя обработчики.
|
То есть, при клике на `TD` событие путешествует по цепочке родителей сначала вниз к элементу ("погружается"), а потом наверх ("всплывает"), по пути задействуя обработчики.
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 4.6 KiB |
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="337px" height="216px" viewBox="0 0 337 216" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||||
|
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>event-order-bubbling.svg</title>
|
||||||
|
<desc>Created with bin/sketchtool.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||||
|
<g id="event-order-bubbling.svg" sketch:type="MSArtboardGroup">
|
||||||
|
<path d="M159.48764,140 L174,186 L60,186 L74.51236,140 L159.48764,140 Z" id="Rectangle-210" fill="#FFDE99" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M180.23146,72 L202,141 L31,141 L52.76854,72 L180.23146,72 Z" id="Rectangle-209" stroke="#CFCE95" stroke-width="18" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M199.611787,20 L228,110 L5,110 L33.388213,20 L199.611787,20 Z" id="Rectangle-208" stroke="#99C0C3" stroke-width="18" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M112.500875,123 L112.500875,110 L112.500875,110 L121.499875,110 L121.499875,123 L112.500875,123 Z M112.500875,141 L112.500875,154.816139 C112.500875,157.302139 114.514875,159.316139 117.000875,159.316139 C119.484875,159.316139 121.499875,157.302139 121.499875,154.816139 L121.499875,141 L112.500875,141 Z M112.500875,92 L112.500875,35.6981394 L102.361875,45.8351394 C100.605875,47.5921394 97.756875,47.5921394 95.998875,45.8351394 C94.240875,44.0771394 94.240875,41.2281394 95.998875,39.4711394 L113.637875,21.8311394 C114.563875,20.9071394 115.789875,20.4821394 117.000875,20.5311394 C118.210875,20.4821394 119.437875,20.9071394 120.361875,21.8311394 L138.001875,39.4711394 C139.758875,41.2281394 139.758875,44.0771394 138.001875,45.8351394 C136.243875,47.5921394 133.394875,47.5921394 131.637875,45.8351394 L121.499875,35.6981394 L121.499875,92 L112.500875,92 Z" id="Fill-46" fill="#5A4739" sketch:type="MSShapeGroup"></path>
|
||||||
|
<text id="1" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#5A4739">
|
||||||
|
<tspan x="210" y="105">1</tspan>
|
||||||
|
</text>
|
||||||
|
<text id="2" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#5A4739">
|
||||||
|
<tspan x="185" y="136">2</tspan>
|
||||||
|
</text>
|
||||||
|
<text id="3" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#EE6B47">
|
||||||
|
<tspan x="157" y="181">3</tspan>
|
||||||
|
</text>
|
||||||
|
<text id="Самый-глубокий-элеме" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" line-spacing="17" fill="#8A704D">
|
||||||
|
<tspan x="211" y="181">Самый глубокий </tspan>
|
||||||
|
<tspan x="211" y="198">элемент</tspan>
|
||||||
|
</text>
|
||||||
|
<path d="M170.5,176.5 L200.5,176.5" id="Line-30" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" stroke-dasharray="3,6" sketch:type="MSShapeGroup"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 21 KiB |
194
2-ui/2-events-and-interfaces/4-event-bubbling/eventflow.svg
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
width="100%" height="100%" viewBox="0 0 640 690">
|
||||||
|
|
||||||
|
<title>DOM Level 3 Events: Event Flow</title>
|
||||||
|
<desc>Alternate description</desc>
|
||||||
|
|
||||||
|
|
||||||
|
<defs id="defs-1">
|
||||||
|
<path id="arrowhead" d="M-9,-4 L0,0 -9,4 Z" stroke-linejoin="round" stroke-linecap="round"/>
|
||||||
|
<marker id="blackArrow" viewBox="-13 -5 14 10" refX="-4" markerWidth="10" markerHeight="20" orient="auto">
|
||||||
|
<use xlink:href="#arrowhead" stroke="black" fill="black" />
|
||||||
|
</marker>
|
||||||
|
<marker id="redArrow" viewBox="-13 -5 14 10" refX="-4" markerWidth="10" markerHeight="20" orient="auto">
|
||||||
|
<use xlink:href="#arrowhead" stroke="red" fill="red" />
|
||||||
|
</marker>
|
||||||
|
<marker id="greenArrow" viewBox="-13 -5 14 10" refX="-4" markerWidth="10" markerHeight="20" orient="auto">
|
||||||
|
<use xlink:href="#arrowhead" stroke="green" fill="green" />
|
||||||
|
</marker>
|
||||||
|
|
||||||
|
<filter x="-5%" y="-5%" width="120%" height="120%" id="dropShadow">
|
||||||
|
<feGaussianBlur stdDeviation="2 2" in="SourceAlpha"/>
|
||||||
|
<feOffset dx="4" dy="4"/>
|
||||||
|
<feComponentTransfer result="shadow">
|
||||||
|
<feFuncA type="linear" slope=".55" intercept="0"/>
|
||||||
|
</feComponentTransfer>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
|
||||||
|
<g id="nodes" font-family="Verdana, sans-serif" font-size="18" fill="black" text-anchor="middle" stroke="none" stroke-width="2">
|
||||||
|
<g id="Window-node" transform="translate(310, 10)">
|
||||||
|
<a xlink:href="../DOM3-Events.html#glossary-window" target="_parent">
|
||||||
|
<rect x="-70" y="0" width="140" height="40" fill="gainsboro" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26">Window</text>
|
||||||
|
</a>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="document-node" transform="translate(310, 80)">
|
||||||
|
<a xlink:href="../DOM3-Events.html#glossary-document" target="_parent">
|
||||||
|
<rect x="-60" y="0" width="120" height="40" fill="gainsboro" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26">Document</text>
|
||||||
|
</a>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="html-node" transform="translate(310, 150)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><html></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="body-node" transform="translate(310, 220)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><body></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="table-node" transform="translate(310, 290)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><table></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="tbody-node" transform="translate(310, 360)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><tbody></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="tr_1-node" transform="translate(140, 450)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><tr></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="tr_2-node" transform="translate(500, 450)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><tr></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<g id="tr_1_td_1-node" transform="translate(70, 540)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><td></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="tr_1_td_1_text-node" transform="translate(70, 610)">
|
||||||
|
<ellipse cx="0" cy="35" rx="64" ry="35" fill="steelblue" stroke="black" filter="url(#dropShadow)"/>
|
||||||
|
<text x="0" y="40" font-size="15" fill="white" text-anchor="middle">Shady Grove</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<g id="tr_1_td_2-node" transform="translate(210, 540)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><td></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="tr_1_td_2_text-node" transform="translate(210, 610)">
|
||||||
|
<ellipse cx="0" cy="35" rx="64" ry="35" fill="steelblue" stroke="black" filter="url(#dropShadow)"/>
|
||||||
|
<text x="0" y="40" font-size="15" fill="white" text-anchor="middle">Aeolian</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<g id="tr_2_td_1-node" transform="translate(430, 540)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="blue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26" fill="white"><td></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="tr_2_td_1_text-node" transform="translate(430, 610)">
|
||||||
|
<ellipse cx="0" cy="35" rx="64" ry="35" fill="steelblue" stroke="black" filter="url(#dropShadow)"/>
|
||||||
|
<text x="0" y="40" font-size="15" fill="white" text-anchor="middle">
|
||||||
|
<tspan x="0" y="34">Over the River,</tspan> <tspan x="0" y="54">Charlie</tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<g id="tr_2_td_2-node" transform="translate(570, 540)">
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="lightskyblue" stroke="black" filter="url(#dropShadow)" />
|
||||||
|
<text x="0" y="26"><td></text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="tr_2_td_2_text-node" transform="translate(570, 610)">
|
||||||
|
<ellipse cx="0" cy="35" rx="64" ry="35" fill="steelblue" stroke="black" filter="url(#dropShadow)"/>
|
||||||
|
<text x="0" y="40" font-size="15" fill="white" text-anchor="middle">Dorian</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="edges">
|
||||||
|
<line id="window-document" x1="310" y1="50" x2="310" y2="73" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
<line id="document-html" x1="310" y1="120" x2="310" y2="143" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
<line id="html-body" x1="310" y1="190" x2="310" y2="213" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
<line id="body-table" x1="310" y1="260" x2="310" y2="283" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
<line id="table-tbody" x1="310" y1="330" x2="310" y2="353" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
<path id="tbody-tr_1" fill="none" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"
|
||||||
|
d="M310,400 Q310,420 260,420 H160 Q140,420 140,443"/>
|
||||||
|
<path id="tbody-tr_2" fill="none" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"
|
||||||
|
d="M310,400 Q310,420 380,420 H480 Q500,420 500,443"/>
|
||||||
|
<path id="tr_1-tr_2_td_1" fill="none" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"
|
||||||
|
d="M140,490 Q140,510 120,510 H90 Q70,510 70,533"/>
|
||||||
|
<path id="tr_1-tr_2_td_2" fill="none" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"
|
||||||
|
d="M140,490 Q140,510 160,510 H190 Q210,510 210,533"/>
|
||||||
|
<path id="tr_2-tr_2_td_1" fill="none" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"
|
||||||
|
d="M500,490 Q500,510 480,510 H450 Q430,510 430,533"/>
|
||||||
|
<path id="tr_2-tr_2_td_2" fill="none" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"
|
||||||
|
d="M500,490 Q500,510 540,510 H550 Q570,510 570,533"/>
|
||||||
|
<line id="tr_1_td_1-text" x1="70" y1="580" x2="70" y2="603" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
<line id="tr_1_td_2-text" x1="210" y1="580" x2="210" y2="603" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
<line id="tr_2_td_1-text" x1="430" y1="580" x2="430" y2="603" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
<line id="tr_2_td_2-text" x1="570" y1="580" x2="570" y2="603" stroke="black" stroke-width="2" marker-end="url(#blackArrow)"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="event-flow" stroke-dasharray="10,5">
|
||||||
|
<g id="capture_phase">
|
||||||
|
<a xlink:href="../DOM3-Events.html#glossary-capture-phase" target="_parent"><text fill="red" font-family="Verdana, sans-serif" font-size="20" font-weight="bold" text-anchor="middle"><tspan x="150" y="220">Capture</tspan> <tspan x="150" y="240">Phase</tspan> <tspan x="150" y="260">(1)</tspan></text></a>
|
||||||
|
|
||||||
|
<path id="capture_phase_arrow" fill="none" stroke="red" stroke-width="3" marker-end="url(#redArrow)" stroke-linecap="round"
|
||||||
|
d="M235,28 C195,25 195,75 238,85 "/>
|
||||||
|
<use xlink:href="#capture_phase_arrow" x="5" y="70" />
|
||||||
|
<use xlink:href="#capture_phase_arrow" x="10" y="140" />
|
||||||
|
<use xlink:href="#capture_phase_arrow" x="10" y="210" />
|
||||||
|
<use xlink:href="#capture_phase_arrow" x="10" y="280" />
|
||||||
|
<path id="capture_phase_arrow2" fill="none" stroke="red" stroke-width="3" marker-end="url(#redArrow)" stroke-linecap="round"
|
||||||
|
d="M245,378 C205,375 205,473 428,458 "/>
|
||||||
|
<path id="capture_phase_arrow3" fill="none" stroke="red" stroke-width="3" marker-end="url(#redArrow)" stroke-linecap="round"
|
||||||
|
stroke-dasharray="none" d="M428,473 C330,470 330,533 363,548 "/>
|
||||||
|
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="target_phase">
|
||||||
|
<a xlink:href="../DOM3-Events.html#glossary-target-phase" target="_parent"><text fill="blue" font-family="Verdana, sans-serif" font-size="20" font-weight="bold" text-anchor="middle"><tspan x="337" y="580">Target</tspan> <tspan x="337" y="600">Phase</tspan> <tspan x="337" y="620">(2)</tspan></text></a>
|
||||||
|
|
||||||
|
<rect x="-50" y="0" width="100" height="40" rx="5" ry="5" fill="none" stroke="black" stroke-width="5" stroke-dasharray="none"
|
||||||
|
transform="translate(430, 540)"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g id="bubble_phase">
|
||||||
|
<a xlink:href="../DOM3-Events.html#glossary-bubbling-phase" target="_parent"><text fill="green" font-family="Verdana, sans-serif" font-size="20" font-weight="bold" text-anchor="middle"><tspan x="490" y="320">Bubbling</tspan> <tspan x="490" y="340">Phase</tspan> <tspan x="490" y="360">(3)</tspan></text></a>
|
||||||
|
|
||||||
|
<path id="bubble_phase_arrow3" fill="none" stroke="green" stroke-width="3" marker-end="url(#greenArrow)" stroke-linecap="round"
|
||||||
|
stroke-dasharray="none" d="M492,548 C630,483 630,470 562,473"/>
|
||||||
|
<path id="bubble_phase_arrow2" fill="none" stroke="green" stroke-width="3" marker-end="url(#greenArrow)" stroke-linecap="round"
|
||||||
|
d="M565,457 C605,447 605,398 377,388"/>
|
||||||
|
<path id="bubble_phase_arrow" fill="none" stroke="green" stroke-width="3" marker-end="url(#greenArrow)" stroke-linecap="round"
|
||||||
|
d="M375,375 C415,372 415,332 375,322"/>
|
||||||
|
<use xlink:href="#bubble_phase_arrow" x="0" y="-70" />
|
||||||
|
<use xlink:href="#bubble_phase_arrow" x="0" y="-140" />
|
||||||
|
<path id="bubble_phase_arrow4" fill="none" stroke="green" stroke-width="3" marker-end="url(#greenArrow)" stroke-linecap="round"
|
||||||
|
d="M375,165 C425,162 425,122 385,112"/>
|
||||||
|
<path id="bubble_phase_arrow" fill="none" stroke="green" stroke-width="3" marker-end="url(#greenArrow)" stroke-linecap="round"
|
||||||
|
d="M385,95 C435,92 435,52 395,42"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
|
@ -79,7 +79,7 @@ function highlight(node) {
|
||||||
|
|
||||||
Естественно, клик может произойти внутри `<td>`, на элементе `<strong>`. Такой клик будет пойман единым обработчиком, но `target` у него будет не `<td>`, а `<strong>`:
|
Естественно, клик может произойти внутри `<td>`, на элементе `<strong>`. Такой клик будет пойман единым обработчиком, но `target` у него будет не `<td>`, а `<strong>`:
|
||||||
|
|
||||||
<img src="bagua.png">
|
<img src="bagua-bubble.svg">
|
||||||
|
|
||||||
Внутри обработчика `table.onclick` мы должны по `event.target` разобраться, в каком именно `<td>` был клик.
|
Внутри обработчика `table.onclick` мы должны по `event.target` разобраться, в каком именно `<td>` был клик.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="320px" height="216px" viewBox="0 0 320 216" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||||
|
<!-- Generator: bin/sketchtool 1.3 (252) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>bagua-bubble.svg</title>
|
||||||
|
<desc>Created with bin/sketchtool.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||||
|
<g id="bagua-bubble.svg" sketch:type="MSArtboardGroup">
|
||||||
|
<path d="M202.48764,140 L217,186 L103,186 L117.51236,140 L202.48764,140 Z" id="Rectangle-210" fill="#FFDE99" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M223.23146,72 L245,141 L74,141 L95.76854,72 L223.23146,72 Z" id="Rectangle-209" stroke="#CFCE95" stroke-width="18" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M242.611787,20 L271,110 L48,110 L76.388213,20 L242.611787,20 Z" id="Rectangle-208" stroke="#99C0C3" stroke-width="18" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M155.500875,123 L155.500875,110 L155.500875,110 L164.499875,110 L164.499875,123 L155.500875,123 Z M155.500875,141 L155.500875,154.816139 C155.500875,157.302139 157.514875,159.316139 160.000875,159.316139 C162.484875,159.316139 164.499875,157.302139 164.499875,154.816139 L164.499875,141 L155.500875,141 Z M155.500875,92 L155.500875,35.6981394 L145.361875,45.8351394 C143.605875,47.5921394 140.756875,47.5921394 138.998875,45.8351394 C137.240875,44.0771394 137.240875,41.2281394 138.998875,39.4711394 L156.637875,21.8311394 C157.563875,20.9071394 158.789875,20.4821394 160.000875,20.5311394 C161.210875,20.4821394 162.437875,20.9071394 163.361875,21.8311394 L181.001875,39.4711394 C182.758875,41.2281394 182.758875,44.0771394 181.001875,45.8351394 C179.243875,47.5921394 176.394875,47.5921394 174.637875,45.8351394 L164.499875,35.6981394 L164.499875,92 L155.500875,92 Z" id="Fill-46" fill="#5A4739" sketch:type="MSShapeGroup"></path>
|
||||||
|
<text id="<table>" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#99C0C3">
|
||||||
|
<tspan x="9" y="30"><table></tspan>
|
||||||
|
</text>
|
||||||
|
<text id="<td>" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#CFCE95">
|
||||||
|
<tspan x="36" y="136"><td></tspan>
|
||||||
|
</text>
|
||||||
|
<text id="<strong>" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" fill="#E8C48E">
|
||||||
|
<tspan x="35" y="181"><strong></tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 3.5 KiB |
|
@ -289,11 +289,8 @@ if ( !jQuery.contains( elem.ownerDocument, elem ) ) {
|
||||||
<li>Можно использовать произвольную библиотеку, такую как jQuery, и работать с Shadow DOM с её использованием. Но возможны проблемки. Выше была продемонстрирована одна из них, могут быть и другие.</li>
|
<li>Можно использовать произвольную библиотеку, такую как jQuery, и работать с Shadow DOM с её использованием. Но возможны проблемки. Выше была продемонстрирована одна из них, могут быть и другие.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
Пока веб-компоненты ещё не являются законченными стандартами, можно попробовать [Polymer](http://www.polymer-project.org) -- это самый известный из полифиллов на тему веб-компонент.
|
||||||
|
|
||||||
Самый известный из полифиллов на тему веб-компонент -- это [Polymer](http://www.polymer-project.org). Он старается их эмулировать по возможности кросс-браузерно, но пока что это довольно-таки сложно, в частности, необходима дополнительная разметка.
|
Он старается их эмулировать по возможности кросс-браузерно, но пока что это довольно-таки сложно, в частности, необходима дополнительная разметка.
|
||||||
|
|
||||||
Текущее состояние веб-стандартов -- "взгляд в будущее". Наверно, будет здорово, когда оно наступит.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -28,7 +28,7 @@ div {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="border-box.png">
|
<img src="border-box.svg">
|
||||||
|
|
||||||
В верхнем случае браузер нарисовал весь элемент размером в `width x height`, в нижнем -- интерпретировал `width/height` как размеры внутренней области.
|
В верхнем случае браузер нарисовал весь элемент размером в `width x height`, в нижнем -- интерпретировал `width/height` как размеры внутренней области.
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 4.3 KiB |
40
3-more/11-css-for-js/10-box-sizing/border-box.svg
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="550px" height="399px" viewBox="0 0 550 399" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||||
|
<!-- Generator: Sketch 3.2.2 (9983) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>border-box</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||||
|
<g id="border-box" sketch:type="MSArtboardGroup">
|
||||||
|
<text id="Содержимое" sketch:type="MSTextLayer" font-family="Times" font-size="18" font-weight="normal" sketch:alignment="middle" fill="#5A4739">
|
||||||
|
<tspan x="306.752441" y="96">Содержимое</tspan>
|
||||||
|
</text>
|
||||||
|
<text id="Содержимое" sketch:type="MSTextLayer" font-family="Times" font-size="18" font-weight="normal" sketch:alignment="middle" fill="#5A4739">
|
||||||
|
<tspan x="306.752441" y="301">Содержимое</tspan>
|
||||||
|
</text>
|
||||||
|
<path d="M218,38 L492,38 L492,145 L218,145 L218,38 Z M232,50 L479,50 L479,133 L232,133 L232,50 Z" id="Path-2" fill="#999647" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M193,243 L517,243 L517,350 L193,350 L193,243 Z M207,255 L504,255 L504,338 L207,338 L207,255 Z" id="Path-2" fill="#999647" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M223,43 L487,43 L487,140 L223,140 L223,43 Z M243,63 L467,63 L467,120 L243,120 L243,63 Z" id="Rectangle-222" fill="#E8C48E" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M198,248 L512,248 L512,345 L198,345 L198,248 Z M218,268 L492,268 L492,325 L218,325 L218,268 Z" id="Rectangle-222" fill="#E8C48E" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M217,20.5 L217,364.570007" id="Line" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" stroke-dasharray="3,6" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path d="M493,20.5 L493,364.570007" id="Line-2" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" stroke-dasharray="3,6" sketch:type="MSShapeGroup"></path>
|
||||||
|
<text sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" sketch:alignment="middle" fill="#EE6C49">
|
||||||
|
<tspan x="317.013672" y="24">border-box</tspan>
|
||||||
|
</text>
|
||||||
|
<text id="content-box" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" sketch:alignment="middle" fill="#EE6B47">
|
||||||
|
<tspan x="313.165039" y="229">content-box</tspan>
|
||||||
|
</text>
|
||||||
|
<ellipse id="Oval-5" stroke="#EE6B47" stroke-width="2" sketch:type="MSShapeGroup" cx="87" cy="183.5" rx="76" ry="43.5"></ellipse>
|
||||||
|
<path d="M157,203 L186,221" id="Line-3" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path id="Line-3-decoration-1" d="M185.887766,220.930337 C183.229857,218.044784 180.951649,215.571452 178.29374,212.685898 C177.186278,214.470142 176.237025,215.999495 175.129563,217.783739 C178.894934,218.885048 182.122395,219.829028 185.887766,220.930337 C185.887766,220.930337 185.887766,220.930337 185.887766,220.930337 Z" stroke="#EE6B47" stroke-width="2" stroke-linecap="square"></path>
|
||||||
|
<path d="M159,165 L191,146" id="Line-4" stroke="#EE6B47" stroke-width="2" stroke-linecap="square" sketch:type="MSShapeGroup"></path>
|
||||||
|
<path id="Line-4-decoration-1" d="M190.814626,146.110066 C187.028309,147.137055 183.782895,148.017331 179.996578,149.04432 C181.068709,150.850015 181.987679,152.397754 183.059811,154.203449 C185.773996,151.370765 188.10044,148.94275 190.814626,146.110066 C190.814626,146.110066 190.814626,146.110066 190.814626,146.110066 Z" stroke="#EE6B47" stroke-width="2" stroke-linecap="square"></path>
|
||||||
|
<text id="border:-5px;" sketch:type="MSTextLayer" font-family="Consolas" font-size="16" font-weight="bold">
|
||||||
|
<tspan x="32" y="176.64193" fill="#999647">border: 5px;</tspan>
|
||||||
|
<tspan x="137.5625" y="176.64193" fill="#8A704D"></tspan>
|
||||||
|
<tspan x="32" y="195.64193" fill="#E8C48E">padding: 20px;</tspan>
|
||||||
|
<tspan x="155.15625" y="195.64193" fill="#8A704D"></tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
|
@ -1,50 +1,31 @@
|
||||||
# Введение в AJAX и COMET
|
# Введение в AJAX и COMET
|
||||||
|
|
||||||
В этой статье AJAX описывается на уровне возможностей и примеров. Рассмотрены особенности асинхронного взаимодействия и примеры использования, но с минимумом технических деталей.
|
В этой главе мы "обзорно", на уровне возможностей и примеров рассмотрим технологию AJAX. Пока что с минимумом технических деталей.
|
||||||
|
|
||||||
Надеюсь, она будет полезна для понимания, что такое AJAX и с чем его едят.
|
Она будет полезна для понимания, что такое AJAX и с чем его едят.
|
||||||
[cut]
|
[cut]
|
||||||
|
|
||||||
|
|
||||||
## Что такое AJAX?
|
## Что такое AJAX?
|
||||||
|
|
||||||
AJAX ("<u>A</u>synchronous <u>J</u>avascript <u>A</u>nd <u>X</u>ml") -- технология обращения к серверу без перезагрузки страницы.
|
AJAX (аббревиатура от "<strong>A</strong>synchronous <strong>J</strong>avascript <strong>A</strong>nd <strong>X</strong>ml") -- технология обращения к серверу без перезагрузки страницы.
|
||||||
|
|
||||||
За счет этого уменьшается время отклика и веб-приложение по интерактивности больше напоминает десктоп.
|
За счет этого уменьшается время отклика и веб-приложение по интерактивности больше напоминает десктоп.
|
||||||
|
|
||||||
Например, при нажатии кнопки голосовать -- из браузера на сервер будет отправлено сообщение, а сервер ответит браузеру, что голос принят.
|
|
||||||
|
|
||||||
<button onclick="vote(this)">Голосовать</button>
|
|
||||||
|
|
||||||
Обратите внимание, текст кнопки после голосования предоставляется сервером и обновляется лишь после его ответа!
|
|
||||||
|
|
||||||
Несмотря на то, что в названии технологии присутствует буква `X` (от слова XML), использовать XML вовсе не обязательно. Под AJAX подразумевают любое общение с сервером без перезагрузки страницы, организованное при помощи JavaScript.
|
Несмотря на то, что в названии технологии присутствует буква `X` (от слова XML), использовать XML вовсе не обязательно. Под AJAX подразумевают любое общение с сервером без перезагрузки страницы, организованное при помощи JavaScript.
|
||||||
|
|
||||||
## Что я могу сделать с помощью AJAX?
|
## Что я могу сделать с помощью AJAX?
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Элементы интерфейса</dt>
|
<dt>Элементы интерфейса</dt>
|
||||||
<dd>
|
<dd>В первую очередь AJAX полезен для форм и кнопок, связанных с элементарными действиями: добавить в корзину, подписаться, и т.п.
|
||||||
В первую очередь AJAX полезен для небольших элементов, связанных с элементарными действиями: добавить в корзину, подписаться, и т.п.
|
|
||||||
|
|
||||||
<table border="0">
|
Сейчас -- в порядке вещей, что такие действия на сайтах осуществляются без перезагрузки страницы.
|
||||||
<tr>
|
|
||||||
<td><img src="/files/tutorial/ajax/intro/can_do_1.png" onclick="alert('Почтамт поможет!')"></td>
|
|
||||||
<td><img src="/files/tutorial/ajax/intro/can_do_2.png" onclick="alert('Да это просто пример :)')"></td>
|
|
||||||
<td><img src="/files/tutorial/ajax/intro/can_do_3.png" onclick="alert('Закажи мне.. Закажи :)');"></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
Сейчас -- в порядке вещей, что голосование на сайтах осуществляется без перезагрузки страницы.
|
|
||||||
</dd>
|
</dd>
|
||||||
<dt>Динамическая подгрузка данных</dt>
|
<dt>Динамическая подгрузка данных</dt>
|
||||||
<dd>Например, дерево, которое при открытии узла запрашивает данные у сервера:
|
<dd>Например, дерево, которое при раскрытии узла запрашивает данные у сервера.</dd>
|
||||||
|
|
||||||
[iframe src="tree.html" height=200 border=1]
|
|
||||||
</dd>
|
|
||||||
<dt>Живой поиск</dt>
|
<dt>Живой поиск</dt>
|
||||||
<dd>
|
<dd>*Живой поиск* -- классический пример использования AJAX, взятый на вооружение современными поисковыми системами.
|
||||||
*Живой поиск* -- классический пример использования AJAX, взятый на вооружение современными поисковыми системами.
|
|
||||||
|
|
||||||
Пользователь начинает печатать поисковую фразу, а JavaScript предлагает возможные варианты, получая список самых вероятных дополнений с сервера.
|
Пользователь начинает печатать поисковую фразу, а JavaScript предлагает возможные варианты, получая список самых вероятных дополнений с сервера.
|
||||||
|
|
||||||
|
@ -52,26 +33,19 @@ AJAX ("<u>A</u>synchronous <u>J</u>avascript <u>A</u>nd <u>X</u>ml") -- техн
|
||||||
|
|
||||||
Код, который это обеспечивает, работает следующим образом.
|
Код, который это обеспечивает, работает следующим образом.
|
||||||
<ol>
|
<ol>
|
||||||
<li>Активируется примерно при каждом нажатии клавиши
|
<li>Код активируется примерно при каждом нажатии клавиши, но не чаще чем раз в 100мс (примерно).</li>
|
||||||
<ul>
|
|
||||||
<li>Время посылки последнего запроса отслеживается</li>
|
|
||||||
<li>Для "обычной" скорости печати - запрос отсылается при каждом нажатии</li>
|
|
||||||
<li>Для "программистской" скорости - каждые несколько нажатий</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>Создается скрытый DIV, который показывается при начале печати</li>
|
<li>Создается скрытый DIV и заполняется ответом сервера:
|
||||||
<li>DIV заполняется ответом сервера
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Текущий результат подсвечен, можно перемещаться и выбирать</li>
|
<li>Текущий результат подсвечен, можно перемещаться и выбирать</li>
|
||||||
<li>При нажатии правой стрелки или при клике -- поиск в подрезультатах</li>
|
<li>При нажатии правой стрелки или при клике -- поиск в подрезультатах</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>Результаты кешируются
|
<li>Результаты запросов кешируются, повторных обращений к серверу не происходит.</li>
|
||||||
<ul>
|
|
||||||
<li>При нажатии на Backspace, обращения к серверу не происходит</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>В Google не только предлагаются варианты, но система тут же инициирует и сам поиск, т.е. не нужно даже жать Enter.</li>
|
<li>В Google не только предлагаются варианты, но система тут же инициирует и сам поиск, т.е. не нужно даже нажимать [key Enter].</li>
|
||||||
</ol>
|
</ol>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
@ -90,7 +64,7 @@ AJAX ("<u>A</u>synchronous <u>J</u>avascript <u>A</u>nd <u>X</u>ml") -- техн
|
||||||
|
|
||||||
[COMET](http://ru.wikipedia.org/wiki/Comet_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) -- общий термин, описывающий различные техники получения данных по инициативе сервера.
|
[COMET](http://ru.wikipedia.org/wiki/Comet_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) -- общий термин, описывающий различные техники получения данных по инициативе сервера.
|
||||||
|
|
||||||
Можно сказать, что AJAX -- это "нажал на кнопку -- получил результат", а COMET -- это "просто сижу и наблюдаю за результатами".
|
Можно сказать, что AJAX -- это "отправил запрос -- получил результат", а COMET -- это "непрерывный канал, по которому приходят данные".
|
||||||
|
|
||||||
Примеры COMET-приложений:
|
Примеры COMET-приложений:
|
||||||
|
|
||||||
|
@ -110,22 +84,3 @@ AJAX ("<u>A</u>synchronous <u>J</u>avascript <u>A</u>nd <u>X</u>ml") -- техн
|
||||||
|
|
||||||
В принципе, можно начать их использовать и не зная, что внутри. Но, скорее всего, вам всё равно понадобится отлаживать ошибки, смотреть детали коммуникации, выбирать наилучшее решение для конкретной задачи, и здесь обязательно разбираться, как это всё работает.
|
В принципе, можно начать их использовать и не зная, что внутри. Но, скорее всего, вам всё равно понадобится отлаживать ошибки, смотреть детали коммуникации, выбирать наилучшее решение для конкретной задачи, и здесь обязательно разбираться, как это всё работает.
|
||||||
|
|
||||||
|
|
||||||
[head]
|
|
||||||
<script>
|
|
||||||
function vote(outputElem) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhr.open('GET', '/files/tutorial/ajax/intro/vote.php', true);
|
|
||||||
|
|
||||||
xhr.onreadystatechange = function() {
|
|
||||||
if (xhr.readyState != 4) return;
|
|
||||||
|
|
||||||
outputElem.innerHTML = xhr.responseText;
|
|
||||||
}
|
|
||||||
|
|
||||||
outputElem.innerHTML = '...';
|
|
||||||
xhr.send(null);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
[/head]
|
|
0
3-more/10-ajax/1-ajax-intro/suggest.png → 3-more/2-ajax/1-ajax-intro/suggest.png
Executable file → Normal file
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
0
3-more/10-ajax/1-ajax-intro/tree.html → 3-more/2-ajax/1-ajax-intro/tree.html
Executable file → Normal file
0
3-more/10-ajax/10-ajax-jsonp/scriptRequest.js → 3-more/2-ajax/10-ajax-jsonp/scriptRequest.js
Executable file → Normal file
0
3-more/10-ajax/11-server-sent-events/browser.js → 3-more/2-ajax/11-server-sent-events/browser.js
Executable file → Normal file
0
3-more/10-ajax/11-server-sent-events/eventsource/browser.js → 3-more/2-ajax/11-server-sent-events/eventsource/browser.js
Executable file → Normal file
0
3-more/10-ajax/11-server-sent-events/eventsource/index.html → 3-more/2-ajax/11-server-sent-events/eventsource/index.html
Executable file → Normal file
0
3-more/10-ajax/11-server-sent-events/eventsource/index.js → 3-more/2-ajax/11-server-sent-events/eventsource/index.js
Executable file → Normal file
0
3-more/10-ajax/11-server-sent-events/index.js → 3-more/2-ajax/11-server-sent-events/index.js
Executable file → Normal file
0
3-more/10-ajax/12-ajax-iframe/samedomain.js → 3-more/2-ajax/12-ajax-iframe/samedomain.js
Executable file → Normal file
0
3-more/10-ajax/12-ajax-iframe/samedomain/.zip → 3-more/2-ajax/12-ajax-iframe/samedomain/.zip
Executable file → Normal file
0
3-more/10-ajax/12-ajax-iframe/samedomain/iframe.js → 3-more/2-ajax/12-ajax-iframe/samedomain/iframe.js
Executable file → Normal file
0
3-more/10-ajax/12-ajax-iframe/samedomain/index.html → 3-more/2-ajax/12-ajax-iframe/samedomain/index.html
Executable file → Normal file
0
3-more/10-ajax/12-ajax-iframe/samedomain/samedomain.js → 3-more/2-ajax/12-ajax-iframe/samedomain/samedomain.js
Executable file → Normal file
0
3-more/10-ajax/12-ajax-iframe/samedomain/samedomain.php → 3-more/2-ajax/12-ajax-iframe/samedomain/samedomain.php
Executable file → Normal file
0
3-more/10-ajax/13-ajax-iframe-htmlfile/activex/.zip → 3-more/2-ajax/13-ajax-iframe-htmlfile/activex/.zip
Executable file → Normal file
0
3-more/10-ajax/13-ajax-iframe-htmlfile/activex/activex.js → 3-more/2-ajax/13-ajax-iframe-htmlfile/activex/activex.js
Executable file → Normal file
0
3-more/10-ajax/13-ajax-iframe-htmlfile/activex/index.html → 3-more/2-ajax/13-ajax-iframe-htmlfile/activex/index.html
Executable file → Normal file
0
3-more/10-ajax/13-ajax-iframe-htmlfile/activex/samedomain.php → 3-more/2-ajax/13-ajax-iframe-htmlfile/activex/samedomain.php
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/name.js → 3-more/2-ajax/14-ajax-iframe-xdomain/name.js
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/name/.zip → 3-more/2-ajax/14-ajax-iframe-xdomain/name/.zip
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/name/anydomain.php → 3-more/2-ajax/14-ajax-iframe-xdomain/name/anydomain.php
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/name/blank.html → 3-more/2-ajax/14-ajax-iframe-xdomain/name/blank.html
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/name/iframe.js → 3-more/2-ajax/14-ajax-iframe-xdomain/name/iframe.js
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/name/index.html → 3-more/2-ajax/14-ajax-iframe-xdomain/name/index.html
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/name/name.js → 3-more/2-ajax/14-ajax-iframe-xdomain/name/name.js
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/postmessage.js → 3-more/2-ajax/14-ajax-iframe-xdomain/postmessage.js
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/postmessage/.zip → 3-more/2-ajax/14-ajax-iframe-xdomain/postmessage/.zip
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/postmessage/anydomain.php → 3-more/2-ajax/14-ajax-iframe-xdomain/postmessage/anydomain.php
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/postmessage/iframe.js → 3-more/2-ajax/14-ajax-iframe-xdomain/postmessage/iframe.js
Executable file → Normal file
0
3-more/10-ajax/14-ajax-iframe-xdomain/postmessage/index.html → 3-more/2-ajax/14-ajax-iframe-xdomain/postmessage/index.html
Executable file → Normal file
0
3-more/10-ajax/15-comet-iframe/comet.png → 3-more/2-ajax/15-comet-iframe/comet.png
Executable file → Normal file
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
0
3-more/10-ajax/15-comet-iframe/iframeComet.js → 3-more/2-ajax/15-comet-iframe/iframeComet.js
Executable file → Normal file
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
В этом разделе предлагаются задачи по теме AJAX.
|
В этом разделе предлагаются задачи по теме AJAX.
|
||||||
|
|
||||||
Конечно же, они требуют взаимодействия с сервером. Чтобы не давать преимущества ни одному из серверных языков программирования ;), мы будем использовать серверную часть, написанную на <a href="http://nodejs.org">Node.JS</a>.
|
Конечно же, они требуют взаимодействия с сервером. Мы будем использовать серверную часть, написанную на JavaScript, на <a href="http://nodejs.org">Node.JS</a>.
|
||||||
|
|
||||||
[cut]
|
[cut]
|
||||||
|
|
||||||
Если вы не использовали Node.JS ранее -- не беспокойтесь. Здесь нашей целью является преимущественно клиентская часть, поэтому прямо сейчас изучать Node.JS не обязательно. Серверные скрипты уже готовы. Нужно только поставить и добавить модулей, чтобы их запускать.
|
Если вы не использовали Node.JS ранее -- не беспокойтесь. Здесь нашей целью является преимущественно клиентская часть, поэтому прямо сейчас изучать Node.JS не обязательно. Серверные скрипты уже готовы. Нужно только поставить Node.JS и модули, чтобы их запускать.
|
||||||
|
|
||||||
|
|
||||||
## Установка
|
## Установка
|
0
3-more/10-ajax/2-ajax-nodejs/example/.zip → 3-more/2-ajax/2-ajax-nodejs/example/.zip
Executable file → Normal file
0
3-more/10-ajax/2-ajax-nodejs/example/index.html → 3-more/2-ajax/2-ajax-nodejs/example/index.html
Executable file → Normal file
0
3-more/10-ajax/2-ajax-nodejs/example/index.js → 3-more/2-ajax/2-ajax-nodejs/example/index.js
Executable file → Normal file
|
@ -7,6 +7,8 @@ function loadPhones() {
|
||||||
|
|
||||||
xhr.open('GET', 'phones.json', true);
|
xhr.open('GET', 'phones.json', true);
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function() {
|
||||||
if (xhr.readyState != 4) return;
|
if (xhr.readyState != 4) return;
|
||||||
|
|
||||||
|
@ -28,8 +30,6 @@ function loadPhones() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xhr.send("");
|
|
||||||
|
|
||||||
button.innerHTML = 'Загружаю...';
|
button.innerHTML = 'Загружаю...';
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ function showPhones(phones) {
|
||||||
```
|
```
|
||||||
|
|
||||||
Полное решение с возможнотью скачать:
|
Полное решение с возможнотью скачать:
|
||||||
[iframe src="phones-list" height="100" border="1" zip]
|
[codetabs src="phones-list" height="100"]
|
||||||
|
|
||||||
Обратите внимание -- код обрабатывает возможную ошибку при чтении JSON при помощи `try..catch`.
|
Обратите внимание -- код обрабатывает возможную ошибку при чтении JSON при помощи `try..catch`.
|
||||||
|
|
||||||
Технически, это такая же ошибка, как и `status != 200`, так как сервер обязан присылать корректный JSON, поэтому если уж обрабатываем ошибки запроса, то и её тоже.
|
Технически, это такая же ошибка, как и `status != 200`. Ведь сервер обязан присылать корректный JSON. Поэтому если уж обрабатываем ошибки запроса, то и её тоже.
|
|
@ -5,9 +5,8 @@
|
||||||
Создайте код, который загрузит файл `phones.json` из текущей директории и выведет все названия телефонов из него в виде списка.
|
Создайте код, который загрузит файл `phones.json` из текущей директории и выведет все названия телефонов из него в виде списка.
|
||||||
|
|
||||||
Демо результата:
|
Демо результата:
|
||||||
[iframe src="phones-list" height="100" border="1"]
|
[iframe src="phones-list" height="100"]
|
||||||
|
|
||||||
|
|
||||||
Исходный код просто выводит содержимое файла (скачайте к себе):
|
Исходный код просто выводит содержимое файла (скачайте к себе):
|
||||||
[iframe src="phones-async" border="1" zip]
|
[codetabs src="phones-async" height="100"]
|
||||||
|
|
|
@ -12,11 +12,7 @@
|
||||||
|
|
||||||
Как правило, `XMLHttpRequest` используют для загрузки данных.
|
Как правило, `XMLHttpRequest` используют для загрузки данных.
|
||||||
|
|
||||||
Разберём его на примере ниже, в котором JavaScript осуществит загрузку файла `phones.json` и вывод содержимого:
|
Для начала посмотрим на пример использования, который загружает файл `phones.json` из текущей директории и выдаёт его содержимое:
|
||||||
|
|
||||||
[iframe src="phones" border="1" zip]
|
|
||||||
|
|
||||||
Код, который выполняется при нажатии на кнопку, по шагам:
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
*!*
|
*!*
|
||||||
|
@ -46,21 +42,27 @@ if (xhr.status != 200) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Далее мы более подробно разберём основные методы и свойства `xhr`.
|
В действии:
|
||||||
|
|
||||||
## Методы open, send и abort
|
[codetabs src="phones"]
|
||||||
|
|
||||||
Эти три метода управляют основным потоком запроса:
|
Далее мы более подробно разберём основные методы и свойства объекта `XMLHttpRequest`, в том числе те, которые были использованы в этом коде.
|
||||||
|
|
||||||
|
## Настроить: open
|
||||||
|
|
||||||
|
Синтаксис:
|
||||||
|
```js
|
||||||
|
xhr.open(method, URL, async, user, password)
|
||||||
|
```
|
||||||
|
|
||||||
|
Этот метод -- как правило, вызывается первым после создания объекта `XMLHttpRequest`.
|
||||||
|
|
||||||
<dl>
|
|
||||||
<dt>`open(method, URL, async, user, password)`</dt>
|
|
||||||
<dd>
|
|
||||||
Задаёт основные параметры запроса:
|
Задаёт основные параметры запроса:
|
||||||
<ul>
|
<ul>
|
||||||
<li>`method` -- HTTP-метод. Как правило, используется GET либо POST, хотя доступны и более экзотические, вроде TRACE/DELETE/PUT и т.п.</li>
|
<li>`method` -- HTTP-метод. Как правило, используется GET либо POST, хотя доступны и более экзотические, вроде TRACE/DELETE/PUT и т.п.</li>
|
||||||
<li>`URL` -- адрес запроса. Можно использовать не только http/https, но и другие протоколы, например `ftp://` и `file://`.
|
<li>`URL` -- адрес запроса. Можно использовать не только http/https, но и другие протоколы, например `ftp://` и `file://`.
|
||||||
|
|
||||||
**При этом есть ограничения безопасности, называемые "Same Origin Policy": запрос со страницы можно отправлять только на тот же `протокол://домен:порт`, с которого она пришла. В следующих главах мы рассмотрим, как их можно обойти.**
|
При этом есть ограничения безопасности, называемые "Same Origin Policy": запрос со страницы можно отправлять только на тот же `протокол://домен:порт`, с которого она пришла. В следующих главах мы рассмотрим, как их можно обойти.
|
||||||
</li>
|
</li>
|
||||||
<li>`async` -- если установлено в `false`, то запрос производится синхронно, если `true` -- асинхронно.
|
<li>`async` -- если установлено в `false`, то запрос производится синхронно, если `true` -- асинхронно.
|
||||||
|
|
||||||
|
@ -71,18 +73,25 @@ if (xhr.status != 200) {
|
||||||
<li>`user`, `password` -- логин и пароль для HTTP-авторизации, если нужны.</li>
|
<li>`user`, `password` -- логин и пароль для HTTP-авторизации, если нужны.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</dd>
|
[warn header="Вызов `open` не открывает соединение"]
|
||||||
<dt>`send([body])`</dt>
|
Заметим, что вызов `open`, в противоположность своему названию (`open` - англ. "открыть") не открывает соединение. Он лишь настраивает запрос, а коммуникация инициируется методом `send`.
|
||||||
<dd>Отправить запрос на сервер.
|
[/warn]
|
||||||
|
## Отослать данные: send
|
||||||
|
|
||||||
В `body` находится *тело* запроса. Не у всякого запроса есть тело, например у GET-запросов тела нет.
|
Синтаксис:
|
||||||
|
```js
|
||||||
|
xhr.send([body])
|
||||||
|
```
|
||||||
|
|
||||||
С другой стороны, в POST основные данные как раз передаются через `body`.</dd>
|
Именно этод метод открывает соединение и отправляет запрос на сервер.
|
||||||
<dt>`abort()`</dt>
|
|
||||||
<dd>Прерывает выполнение запроса.</dd>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
## Свойства status, statusText, responseText и responseXML
|
В `body` находится *тело* запроса. Не у всякого запроса есть тело, например у GET-запросов тела нет, а у POST -- основные данные как раз передаются через `body`.
|
||||||
|
|
||||||
|
## Отмена: abort
|
||||||
|
|
||||||
|
Вызов `xhr.abort()` прерывает выполнение запроса.
|
||||||
|
|
||||||
|
## Ответ: status, statusText, responseText
|
||||||
|
|
||||||
Основные свойства, содержащие ответ сервера:
|
Основные свойства, содержащие ответ сервера:
|
||||||
|
|
||||||
|
@ -92,40 +101,53 @@ if (xhr.status != 200) {
|
||||||
<dt>`statusText`</dt>
|
<dt>`statusText`</dt>
|
||||||
<dd>Текстовое описание статуса от сервера: `OK` `Not Found`, `Forbidden` и так далее.</dd>
|
<dd>Текстовое описание статуса от сервера: `OK` `Not Found`, `Forbidden` и так далее.</dd>
|
||||||
<dt>`responseText`</dt>
|
<dt>`responseText`</dt>
|
||||||
<dd>Ответ сервера в виде текста.</dd>
|
<dd>Текст ответа сервера.</dd>
|
||||||
<dt>`responseXml`</dt>
|
</dl>
|
||||||
|
|
||||||
|
Есть и ещё одно свойство, которое используется гораздо реже:
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt>`responseXML`</dt>
|
||||||
<dd>Если сервер вернул XML, снабдив его правильным заголовком `Content-type: text/xml`, то браузер создаст из него XML-документ. По нему можно будет делать запросы `xhr.responseXml.querySelector("...")` и другие.
|
<dd>Если сервер вернул XML, снабдив его правильным заголовком `Content-type: text/xml`, то браузер создаст из него XML-документ. По нему можно будет делать запросы `xhr.responseXml.querySelector("...")` и другие.
|
||||||
|
|
||||||
Как правило, при общении с сервером используют не XML, а JSON. То есть, сервер возвращает JSON в виде текста, который браузер превращает в объект вызовом `JSON.parse(xhr.responseText)`.
|
Оно используется редко, так как обычно используют не XML, а JSON. То есть, сервер возвращает JSON в виде текста, который браузер превращает в объект вызовом `JSON.parse(xhr.responseText)`.
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
## Синхронные и асинхронные запросы
|
||||||
|
|
||||||
## Асинхронный вызов
|
Если в методе `open` установить параметр `async` равным `false` или просто забыть его указать, то запрос будет синхронным.
|
||||||
|
|
||||||
Синхронные вызовы имеют ряд важных отличий от асинхронных:
|
Синхронные вызовы используются чрезвычайно редко, так как блокируют взаимодействие со страницей до окончания загрузки. Посетитель не может даже прокручивать её. Никакой JavaScript не может быть выполнен, пока синхронный вызов не завершён -- в общем, в точности те же ограничения как `alert`.
|
||||||
|
|
||||||
<ul>
|
```js
|
||||||
<li>Блокируют взаимодействие со страницей до окончания загрузки. Посетитель не может даже прокручивать её.</li>
|
// Синхронный запрос
|
||||||
<li>Если синхронный вызов занял слишком много времени, то браузер предложит закрыть "зависшую" страницу.</li>
|
xhr.open('GET', 'phones.json', *!*false*/!*);
|
||||||
<li>Кроме того, забегая вперёд, заметим, что ряд продвинутых возможностей, таких как возможность делать запросы на другой домен и указывать таймаут, в синхронном режиме не работают.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
**Поэтому, как правило, используют асинхронные вызовы.**
|
// Отсылаем его
|
||||||
|
xhr.send();
|
||||||
|
*!*
|
||||||
|
// ...весь JavaScript "подвиснет", пока запрос не завершится
|
||||||
|
*/!*
|
||||||
|
```
|
||||||
|
|
||||||
|
Если синхронный вызов занял слишком много времени, то браузер предложит закрыть "зависшую" страницу.
|
||||||
|
|
||||||
|
Из-за такой блокировки получается, что нельзя отослать два запроса одновременно. Кроме того, забегая вперёд, заметим, что ряд продвинутых возможностей, таких как возможность делать запросы на другой домен и указывать таймаут, в синхронном режиме не работают.
|
||||||
|
|
||||||
|
Из всего вышесказанного уже должно быть понятно, что синхронные запросы используются чрезвычайно редко, а асинхронные -- почти всегда.
|
||||||
|
|
||||||
Для того, чтобы запрос стал асинхронным, укажем параметр `async` равным `true`.
|
Для того, чтобы запрос стал асинхронным, укажем параметр `async` равным `true`.
|
||||||
|
|
||||||
Демо:
|
Изменённый JS-код:
|
||||||
|
|
||||||
[iframe src="phones-async" border zip]
|
|
||||||
|
|
||||||
JS-код изменился:
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
xhr.open('GET', 'phones.json', *!*true*/!*);
|
xhr.open('GET', 'phones.json', *!*true*/!*);
|
||||||
|
|
||||||
|
xhr.send(); // (1)
|
||||||
|
|
||||||
*!*
|
*!*
|
||||||
xhr.onreadystatechange = function() { // (3)
|
xhr.onreadystatechange = function() { // (3)
|
||||||
if (xhr.readyState != 4) return;
|
if (xhr.readyState != 4) return;
|
||||||
|
@ -141,20 +163,21 @@ xhr.onreadystatechange = function() { // (3)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xhr.send(); // (1)
|
|
||||||
|
|
||||||
button.innerHTML = 'Загружаю...'; // (2)
|
button.innerHTML = 'Загружаю...'; // (2)
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
```
|
```
|
||||||
|
|
||||||
Теперь мы отправляем запрос асинхронно:
|
Если в `open` указан третий аргумент `true`, то запрос выполняется асинхронно. Это означает, что после вызова `xhr.send()` в строке `(1)` код не "зависает", а преспокойно продолжает выполняться, выполняется строка `(2)`, а результат приходит через событие `(3)`, мы изучем его чуть позже.
|
||||||
<ol>
|
|
||||||
<li>JavaScript продолжает выполнение после `xhr.send()`.</li>
|
|
||||||
<li>Для того, чтобы показать, что задача "в процессе" -- мы меняем текст кнопки `button`.</li>
|
|
||||||
<li>Скрипт завершается, страница полностью активна, а ответ, когда он появится, вызовет обработчик `onreadystatechange`.</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
**Событие `readystatechange` происходит несколько раз в процессе отсылки и получения ответа. При этом можно посмотреть "текущее состояние запроса" в свойстве `xhr.readyState`.**
|
Полный пример в действии:
|
||||||
|
|
||||||
|
[codetabs src="phones-async"]
|
||||||
|
|
||||||
|
# Событие readystatechange
|
||||||
|
|
||||||
|
Событие `readystatechange` происходит несколько раз в процессе отсылки и получения ответа. При этом можно посмотреть "текущее состояние запроса" в свойстве `xhr.readyState`.
|
||||||
|
|
||||||
|
В примере выше мы использовали только состояние `4` (запрос завершён), но есть и другие.
|
||||||
|
|
||||||
Все состояния, по [спецификации](http://www.w3.org/TR/XMLHttpRequest/#states):
|
Все состояния, по [спецификации](http://www.w3.org/TR/XMLHttpRequest/#states):
|
||||||
|
|
||||||
|
@ -168,24 +191,22 @@ const unsigned short DONE = 4; // запрос завершён
|
||||||
|
|
||||||
Запрос проходит их в порядке `0` -> `1` -> `2` -> `3` -> ... -> `3` -> `4`, состояние `3` повторяется при каждом получении очередного пакета данных по сети.
|
Запрос проходит их в порядке `0` -> `1` -> `2` -> `3` -> ... -> `3` -> `4`, состояние `3` повторяется при каждом получении очередного пакета данных по сети.
|
||||||
|
|
||||||
В данном случае нас интересует состояние `4` (запрос завершён).
|
|
||||||
|
|
||||||
Пример ниже демонстрирует переключение между состояниями. В нём сервер отвечает на запрос `digits`, пересылая по строке из 1000 цифр раз в секунду.
|
Пример ниже демонстрирует переключение между состояниями. В нём сервер отвечает на запрос `digits`, пересылая по строке из 1000 цифр раз в секунду.
|
||||||
|
|
||||||
[iframe src="readystate" height=200 border zip]
|
[codetabs src="readystate"]
|
||||||
|
|
||||||
[warn header="Точка разрыва не гарантирована"]
|
[warn header="Точка разрыва пакетов не гарантирована"]
|
||||||
При `readyState=3` мы можем посмотреть текущие данные в `responseText` и, казалось бы, могли бы работать с этими данными как с "ответом на текущий момент".
|
При состоянии `readyState=3` (получен очередной пакет) мы можем посмотреть текущие данные в `responseText` и, казалось бы, могли бы работать с этими данными как с "ответом на текущий момент".
|
||||||
|
|
||||||
Однако, технически мы не управляем разрывами между сетевыми пакетами. Если протестировать пример выше в локальной сети, то в большинстве браузеров разрывы будут каждые 1000 символов, но в реальности событие может возникнуть на любом байте.
|
Однако, технически мы не управляем разрывами между сетевыми пакетами. Если протестировать пример выше в локальной сети, то в большинстве браузеров разрывы будут каждые 1000 символов, но в реальности пакет может прерваться на любом байте.
|
||||||
|
|
||||||
Вплоть до того, что символ русского языка в кодировке UTF-16 кодируется двумя байтами -- и разрыв может возникнуть *между ними*.
|
Чем это опасно? Хотя бы тем, что символы русского языка в кодировке UTF-8 кодируются двумя байтами каждый -- и разрыв может возникнуть *между ними*.
|
||||||
|
|
||||||
Получится, что при очередном `readyState` в конце `responseText` будет байт-полсимвола, то есть он не будет корректной строкой -- частью ответа! Если скрипт будет предполагать, что это -- полноценная часть ответа, то неизбежны глюки.
|
Получится, что при очередном `readyState` в конце `responseText` будет байт-полсимвола, то есть он не будет корректной строкой -- частью ответа! Если в скрипте как-то по-особому это не обработать, то неизбежны проблемы.
|
||||||
[/warn]
|
[/warn]
|
||||||
|
|
||||||
|
|
||||||
## HTTP-заголовки, методы *RequestHeader
|
## HTTP-заголовки
|
||||||
|
|
||||||
`XMLHttpRequest` умеет как указывать свои заголовки в запросе, так и читать присланные в ответ.
|
`XMLHttpRequest` умеет как указывать свои заголовки в запросе, так и читать присланные в ответ.
|
||||||
|
|
||||||
|
@ -210,7 +231,7 @@ xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
[warn header="Поставленный заголовок нельзя снять"]
|
[warn header="Поставленный заголовок нельзя снять"]
|
||||||
Особенностью `XMLHttpRequest` является то, что отменить `setRequestHeader` невозможно.
|
Особенностью `XMLHttpRequest` является то, что отменить `setRequestHeader` невозможно.
|
||||||
|
|
||||||
Повторные вызовы добавляют информацию к заголовку:
|
Повторные вызовы лишь добавляют информацию к заголовку, например:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
xhr.setRequestHeader('X-Auth', '123');
|
xhr.setRequestHeader('X-Auth', '123');
|
||||||
|
@ -219,7 +240,6 @@ xhr.setRequestHeader('X-Auth', '456');
|
||||||
// в результате будет заголовок:
|
// в результате будет заголовок:
|
||||||
// X-Auth: 123, 456
|
// X-Auth: 123, 456
|
||||||
```
|
```
|
||||||
|
|
||||||
[/warn]
|
[/warn]
|
||||||
|
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -252,9 +272,9 @@ Date: Sat, 08 Sep 2012 16:53:16 GMT
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|
||||||
## Таймаут: свойство и событие timeout
|
## Таймаут
|
||||||
|
|
||||||
Максимальную продолжительность запроса можно задать свойством `timeout`:
|
Максимальную продолжительность асинхронного запроса можно задать свойством `timeout`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
xhr.timeout = 30000; // 30 секунд (в миллисекундах)
|
xhr.timeout = 30000; // 30 секунд (в миллисекундах)
|
||||||
|
@ -268,9 +288,9 @@ xhr.ontimeout = function() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Полный список событий загрузки
|
## Полный список событий
|
||||||
|
|
||||||
Современная [спецификация](http://www.w3.org/TR/XMLHttpRequest/#events) предусматривает следующие события:
|
Современная [спецификация](http://www.w3.org/TR/XMLHttpRequest/#events) предусматривает следующие события по ходу обработки запроса:
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>`loadstart` -- запрос начат.</li>
|
<li>`loadstart` -- запрос начат.</li>
|
||||||
|
@ -279,14 +299,16 @@ xhr.ontimeout = function() {
|
||||||
<li>`error` -- произошла ошибка.</li>
|
<li>`error` -- произошла ошибка.</li>
|
||||||
<li>`load` -- запрос был успешно (без ошибок) завершён.</li>
|
<li>`load` -- запрос был успешно (без ошибок) завершён.</li>
|
||||||
<li>`timeout` -- запрос был прекращён по таймауту.</li>
|
<li>`timeout` -- запрос был прекращён по таймауту.</li>
|
||||||
<li>`loadend` -- запрос был завершён (успешно или неуспешно)</li
|
<li>`loadend` -- запрос был завершён (успешно или неуспешно)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Используя эти события можно более удобно отслеживать загрузку (`onload`) и ошибку (`onerror`), а также количество загруженных данных (`onprogress`).
|
Используя эти события можно более удобно отслеживать загрузку (`onload`) и ошибку (`onerror`), а также количество загруженных данных (`onprogress`).
|
||||||
|
|
||||||
Также поддерживается событие `readystatechange`, которое было описано ранее. Оно появилось гораздо раньше, ещё до появления текущего стандарта. От него можно отказаться в пользу современных событий, если учесть особенности IE8-9 (см. далее).
|
Ранее мы видели ещё одно событие -- `readystatechange`. Оно появилось гораздо раньше, ещё до появления текущего стандарта.
|
||||||
|
|
||||||
## Особенности IE8,9: XDomainRequest
|
В современных браузерах от него можно отказаться в пользу других, необходимо лишь, как мы увидим далее, учесть особенности IE8-9.
|
||||||
|
|
||||||
|
## IE8,9: XDomainRequest
|
||||||
|
|
||||||
В IE8 и IE9 поддержка `XMLHttpRequest` ограничена:
|
В IE8 и IE9 поддержка `XMLHttpRequest` ограничена:
|
||||||
|
|
||||||
|
@ -295,28 +317,30 @@ xhr.ontimeout = function() {
|
||||||
<li>Некорректно поддерживается состояние `readyState = 3`: браузер может сгенерировать его только один раз во время запроса, а не при каждом пакете данных. Кроме того, он не даёт доступ к ответу `responseText` до того, как он будет до конца получен.</li>
|
<li>Некорректно поддерживается состояние `readyState = 3`: браузер может сгенерировать его только один раз во время запроса, а не при каждом пакете данных. Кроме того, он не даёт доступ к ответу `responseText` до того, как он будет до конца получен.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Дело в том, что, когда создавались эти браузеры, спецификации были не до конца проработаны. Поэтому разработчики браузера решили добавить свой объект [XDomainRequest](/xhr-crossdomain) (только IE!), который реализовывал часть возможностей современного стандарта.
|
Дело в том, что, когда создавались эти браузеры, спецификации были не до конца проработаны. Поэтому разработчики браузера решили добавить свой объект `XDomainRequest`, который реализовывал часть возможностей современного стандарта.
|
||||||
|
|
||||||
А обычный `XMLHttpRequest` решили не трогать, чтобы ненароком не сломать существующий код.
|
А обычный `XMLHttpRequest` решили не трогать, чтобы ненароком не сломать существующий код.
|
||||||
|
|
||||||
**Для того, чтобы получить некоторые из современных возможностей, вместо `new XMLHttpRequest()` пишем `new XDomainRequest`.**
|
Мы подробнее поговорим про `XDomainRequest` в главе [](/xhr-crossdomain). Пока лишь заметим, что для того, чтобы получить некоторые из современных возможностей в IE8,9 -- вместо `new XMLHttpRequest()` нужно использовать `new XDomainRequest`.
|
||||||
|
|
||||||
Если кросс-браузерно:
|
Кросс-браузерно:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var XHR = window.XDomainRequest || XMLHttpRequest;
|
var XHR = window.XDomainRequest || XMLHttpRequest;
|
||||||
var xhr = new XHR();
|
var xhr = new XHR();
|
||||||
```
|
```
|
||||||
|
|
||||||
Теперь в IE8,9 поддерживаются события `onload`, `onerror` и `onprogress`.
|
Теперь в IE8,9 поддерживаются события `onload`, `onerror` и `onprogress`. Это именно для IE8,9. Для IE10 обычный `XMLHttpRequest` уже является полноценным.
|
||||||
|
|
||||||
**Ещё одна деталь: IE9- по умолчанию кеширует ответы, не снабжённые антикеш-заголовком. Другие браузеры этого не делают.**
|
### IE9- и кеширование
|
||||||
|
|
||||||
**Чтобы этого избежать, сервер должен добавить в ответ соответствующие антикеш-заголовки, например `Cache-Control: no-cache`.**
|
Обычно ответы на запросы `XMLHttpRequest` кешируются, как и обычные страницы.
|
||||||
|
|
||||||
По правде говоря, использовать заголовки типа `Expires`, `Last-Modified` и `Cache-Control` рекомендуется в любом случае, чтобы дать понять браузеру (не обязательно IE), что ему следует делать.
|
Но IE9- по умолчанию кеширует все ответы, не снабжённые антикеш-заголовком. Другие браузеры этого не делают. Чтобы этого избежать, сервер должен добавить в ответ соответствующие антикеш-заголовки, например `Cache-Control: no-cache`.
|
||||||
|
|
||||||
**Альтернативный вариант -- добавить в URL запроса случайный параметр, предотвращающий кеширование.**
|
Впрочем, использовать заголовки типа `Expires`, `Last-Modified` и `Cache-Control` рекомендуется в любом случае, чтобы дать понять браузеру (не обязательно IE), что ему следует делать.
|
||||||
|
|
||||||
|
Альтернативный вариант -- добавить в URL запроса случайный параметр, предотвращающий кеширование.
|
||||||
|
|
||||||
Например, вместо `xhr.open('GET', 'service', false)` написать:
|
Например, вместо `xhr.open('GET', 'service', false)` написать:
|
||||||
|
|
||||||
|
@ -335,6 +359,8 @@ var xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
xhr.open('GET', '/my/url', true);
|
xhr.open('GET', '/my/url', true);
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function() {
|
||||||
if (this.readyState != 4) return;
|
if (this.readyState != 4) return;
|
||||||
|
|
||||||
|
@ -350,11 +376,9 @@ xhr.onreadystatechange = function() {
|
||||||
|
|
||||||
// получить результат из this.responseText или this.responseXML
|
// получить результат из this.responseText или this.responseXML
|
||||||
}
|
}
|
||||||
|
|
||||||
xhr.send();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Методы:
|
Методы объектов `XMLHttpRequest`:
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>`open(method, url, async, user, password)`</li>
|
<li>`open(method, url, async, user, password)`</li>
|
||||||
|
@ -365,7 +389,7 @@ xhr.send();
|
||||||
<li>`getAllResponseHeaders()`</li>
|
<li>`getAllResponseHeaders()`</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Свойства:
|
Свойства объектов `XMLHttpRequest`:
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>`timeout`</li>
|
<li>`timeout`</li>
|
||||||
|
@ -388,39 +412,3 @@ xhr.send();
|
||||||
<li>`onloadend`</li>
|
<li>`onloadend`</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
[head]
|
|
||||||
<style>
|
|
||||||
.log-div {
|
|
||||||
width: 600px;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function voteSync(outputElem) {
|
|
||||||
var xhr = new XMLHttpRequest(); // (1)
|
|
||||||
|
|
||||||
outputElem.innerHTML = '...';
|
|
||||||
|
|
||||||
xhr.open('GET', '/files/tutorial/ajax/xhr/vote', false);
|
|
||||||
xhr.send(null); // (2)
|
|
||||||
|
|
||||||
outputElem.innerHTML = xhr.responseText; // (3)
|
|
||||||
}
|
|
||||||
|
|
||||||
function vote(outputElem) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhr.open('GET', '/files/tutorial/ajax/xhr/vote', true);
|
|
||||||
|
|
||||||
xhr.onreadystatechange = function() {
|
|
||||||
if (xhr.readyState != 4) return;
|
|
||||||
outputElem.innerHTML = xhr.responseText;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
outputElem.innerHTML = '...';
|
|
||||||
xhr.send(null);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
[/head]
|
|
6
3-more/10-ajax/3-ajax-xmlhttprequest/phones-async/index.html → 3-more/2-ajax/3-ajax-xmlhttprequest/phones-async.view/index.html
Executable file → Normal file
|
@ -12,6 +12,10 @@ function loadPhones() {
|
||||||
|
|
||||||
xhr.open('GET', 'phones.json', true);
|
xhr.open('GET', 'phones.json', true);
|
||||||
|
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function() {
|
||||||
if (xhr.readyState != 4) return;
|
if (xhr.readyState != 4) return;
|
||||||
|
|
||||||
|
@ -27,8 +31,6 @@ function loadPhones() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xhr.send();
|
|
||||||
|
|
||||||
button.innerHTML = 'Загружаю...';
|
button.innerHTML = 'Загружаю...';
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
}
|
}
|
0
3-more/10-ajax/3-ajax-xmlhttprequest/phones-async/index.js → 3-more/2-ajax/3-ajax-xmlhttprequest/phones-async.view/server.js
Executable file → Normal file
0
3-more/10-ajax/3-ajax-xmlhttprequest/phones/index.html → 3-more/2-ajax/3-ajax-xmlhttprequest/phones.view/index.html
Executable file → Normal file
0
3-more/10-ajax/3-ajax-xmlhttprequest/phones/phones.json → 3-more/2-ajax/3-ajax-xmlhttprequest/phones.view/phones.json
Executable file → Normal file
0
3-more/10-ajax/3-ajax-xmlhttprequest/phones/index.js → 3-more/2-ajax/3-ajax-xmlhttprequest/phones.view/server.js
Executable file → Normal file
0
3-more/10-ajax/3-ajax-xmlhttprequest/readystate/index.html → 3-more/2-ajax/3-ajax-xmlhttprequest/readystate.view/index.html
Executable file → Normal file
2
3-more/10-ajax/3-ajax-xmlhttprequest/readystate/index.js → 3-more/2-ajax/3-ajax-xmlhttprequest/readystate.view/server.js
Executable file → Normal file
|
@ -6,6 +6,8 @@ var file = new static.Server('.');
|
||||||
|
|
||||||
function accept(req, res) {
|
function accept(req, res) {
|
||||||
|
|
||||||
|
console.log(req.url);
|
||||||
|
|
||||||
if (req.url == '/digits') {
|
if (req.url == '/digits') {
|
||||||
|
|
||||||
res.writeHead(200, {
|
res.writeHead(200, {
|
0
3-more/10-ajax/5-xhr-longpoll/longpoll.png → 3-more/2-ajax/5-xhr-longpoll/longpoll.png
Executable file → Normal file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |